@ -0,0 +1,94 @@ |
|||
name: 🤠 ABP Studio |
|||
description: Create a report to help us improve the ABP Studio |
|||
labels: [studio] |
|||
body: |
|||
- type: markdown |
|||
attributes: |
|||
value: | |
|||
We welcome bug reports! This template will help us gather the information we need to start the triage process. |
|||
|
|||
Please keep in mind that the GitHub issue tracker is not intended as a general support forum, but for reporting **non-security** bugs and feature requests. |
|||
If you believe you have an issue that affects the SECURITY of the platform, please do NOT create an issue and instead email your issue details to info@abp.io. |
|||
For other types of questions, consider using [StackOverflow](https://stackoverflow.com/questions/tagged/abp). |
|||
- type: checkboxes |
|||
id: searched |
|||
attributes: |
|||
label: Is there an existing issue for this? |
|||
description: Please search to see if an issue already exists for the bug you encountered or feature request ([abp/issues](https://github.com/abpframework/abp/issues?q=is%3Aopen+is%3Aissue+label%3Astudio)). |
|||
options: |
|||
- label: I have searched the existing issues |
|||
required: true |
|||
- type: textarea |
|||
id: background |
|||
attributes: |
|||
label: Description |
|||
description: Please share a clear and concise description of the problem. |
|||
placeholder: Description |
|||
validations: |
|||
required: true |
|||
- type: markdown |
|||
attributes: |
|||
value: | |
|||
## Setup |
|||
Please provide more information on your ABP Studio setup. |
|||
- type: input |
|||
id: version |
|||
attributes: |
|||
label: Version |
|||
description: Which version of ABP Studio are you using? |
|||
placeholder: Version |
|||
validations: |
|||
required: true |
|||
- type: dropdown |
|||
id: Operation-System |
|||
attributes: |
|||
label: Operation System |
|||
description: What is the operation system of the computer? |
|||
options: |
|||
- Windows (Default) |
|||
- Linux |
|||
- macOS |
|||
- Others |
|||
validations: |
|||
required: true |
|||
- type: textarea |
|||
id: solution-config |
|||
attributes: |
|||
label: Solution Configuration |
|||
description: | |
|||
If there is an open solution, what are the configurations of the solution? |
|||
🧐 Hint: You can see all the information about your solution from the configuration window, which opens when you right-click on the [solution](https://abp.io/docs/latest/studio/solution-explorer#solution) and click on the `Solution Configuration` button. |
|||
placeholder: | |
|||
- **Template**: app |
|||
- **Created ABP Studio Version**: 0.7.9 |
|||
- **Tiered**: No |
|||
- **UI Framework**: mvc |
|||
- **Theme**: leptonx |
|||
- **Theme Style**: system |
|||
- **Database Provider**: ef |
|||
- **Database Management System**: sqlserver |
|||
- **Separate Tenant Schema**: No |
|||
- **Mobile Framework**: none |
|||
- **Public Website**: No |
|||
- **Optional Modules**: |
|||
* GDPR |
|||
* TextTemplateManagement |
|||
* LanguageManagement |
|||
* AuditLogging |
|||
* SaaS |
|||
* OpenIddictAdmin |
|||
validations: |
|||
required: false |
|||
- type: markdown |
|||
attributes: |
|||
value: | |
|||
--- |
|||
- type: textarea |
|||
id: other-info |
|||
attributes: |
|||
label: Other information |
|||
description: | |
|||
If you have an idea where the problem might lie, let us know that here. Please include any pointers to code, relevant changes, or related issues you know of. |
|||
placeholder: Other information |
|||
validations: |
|||
required: false |
|||
@ -1,3 +1,3 @@ |
|||
## Contribution |
|||
|
|||
See the [contribution guide](docs/en/Contribution/Index.md). |
|||
The contribution guide is available at [contribution guide](docs/en/contribution/index.md). |
|||
|
|||
@ -1,8 +1,9 @@ |
|||
{ |
|||
"culture": "en", |
|||
"texts": { |
|||
"AbpTitle": "Read All Blog Posts", |
|||
"AbpTitle": "New Blog Post | ABP.IO", |
|||
"AbpDescription": "ABP is an open source application framework focused on AspNet Core based web application development. Don't repeat yourself, focus on your own business code.", |
|||
"AbpDefinition": "ABP blog for .NET development, cross-platform, ASP.NET application templates, ABP-related news and more..." |
|||
"AbpDefinition": "Create a new blog post and share your knowledge and experience with ABP.", |
|||
"Blogs": "Blog Posts" |
|||
} |
|||
} |
|||
@ -1,10 +0,0 @@ |
|||
using Volo.Abp.Localization; |
|||
|
|||
namespace AbpIoLocalization.Commercial.Localization |
|||
{ |
|||
[LocalizationResourceName("AbpIoCommercial")] |
|||
public class AbpIoCommercialResource |
|||
{ |
|||
|
|||
} |
|||
} |
|||
@ -1,10 +0,0 @@ |
|||
using Volo.Abp.Localization; |
|||
|
|||
namespace AbpIoLocalization.Community.Localization |
|||
{ |
|||
[LocalizationResourceName("AbpIoCommunity")] |
|||
public class AbpIoCommunityResource |
|||
{ |
|||
|
|||
} |
|||
} |
|||
|
After Width: | Height: | Size: 342 KiB |
@ -0,0 +1,62 @@ |
|||
|
|||
# The new ABP Platform is live! |
|||
|
|||
We're thrilled to announce that the **new ABP.IO Platform is now live!** Our team has been hard at unifying and enhancing the entire platform to deliver a seamless, user-friendly experience. Here's what's new: |
|||
|
|||
|
|||
### Unified domain and enhanced navigation 🌍 |
|||
All our services are now consolidated under a single domain; [abp.io](https://abp.io). This means you no longer need to navigate through multiple subdomains. The new mega menu makes finding what you need easier and faster. |
|||
|
|||
|
|||
### Modern design and improved UX 🎨 |
|||
The platform boasts a fresh, modern design aimed at improving both aesthetics and functionality. This redesign enhances usability, making your interaction with ABP.IO more intuitive. |
|||
|
|||
|
|||
|
|||
### Documentation in one place 📃 |
|||
We’ve combined the ABP (open-source) and ABP Commercial (paid) documents into a single, comprehensive resource. This unified documentation will help you find what you're looking for more efficiently. The new documentation address is [abp.io/docs](https://abp.io/docs). When you switch to old ABP versions before v8.3, you will see the old documents are still available. |
|||
|
|||
|
|||
|
|||
### Introducing "ABP Studio Community Edition" 🪄 |
|||
We're excited to introduce the **ABP Studio Community Edition**, which is now **available for free**. This edition provides powerful tools to streamline your development process. You can easily create a new project with a configuration wizard in ABP Studio. It also provides module management, which means you can add/remove an ABP Module easily. You can also debug your microservice project and track the HTTP requests easily. Connecting your local development environment to a local or remote Kubernetes cluster is another cool feature of ABP Studio. We aim for ABP Studio to be the primary tool for ABP developers to manage their projects. |
|||
|
|||
> Download ABP Studio 👉 [abp.io/studio](https://abp.io/studio). |
|||
|
|||
|
|||
### Enhanced "ABP CLI" 🚀 |
|||
ABP CLI is also renewed. The new CLI is compatible with ABP Studio. It adds new commands. The new CLI is now available on NuGet at [nuget.org/packages/Volo.Abp.Studio.Cli](https://www.nuget.org/packages/Volo.Abp.Studio.Cli). It's a dotnet global tool. When you install ABP Studio, the new ABP CLI is automatically installed. You can still use the old ABP CLI commands. To use the legacy ABP CLI commands just add `--old` parameter to your commands. |
|||
|
|||
> The docs of the new ABP CLI 👉 [abp.io/docs/latest/cli](https://abp.io/docs/latest/cli). |
|||
|
|||
|
|||
|
|||
### 20% Celebration discount 💰 |
|||
To celebrate the launch of the new platform, we're offering a **20% discount** for a limited time. This discount is valid for all new purchases, renewing existing licenses and buying additional developer seats. |
|||
|
|||
> Discounted prices 👉 [abp.io/pricing](https://abp.io/pricing). |
|||
|
|||
|
|||
### Existing customers 🛂 |
|||
In terms of licensing rules, existing customers will not be affected by this change. You can manage your license just like before at [abp.io/my-organizations](https://abp.io/my-organizations). |
|||
|
|||
> The new support website address 👉 [abp.io/support](https://abp.io/support). |
|||
|
|||
--- |
|||
|
|||
### Why choose the ABP Platform? 🙄 |
|||
ABP Platform simplifies modern software development with well-architected startup templates, modular design infrastructure, multi-tenancy support, comprehensive security features, and a vibrant community. If you are starting a new web project or transforming your legacy application, ABP is the perfect solution! If you still wonder why you need such a solution, see [abp.io/why-choose-abp](https://abp.io/why-choose-abp). |
|||
|
|||
There are several startup ASP.NET Core templates for your requirements. Read [abp.io/how-it-works](https://abp.io/how-it-works) page to understand ABP's approach. We have a FAQ page where you can find answers to many of your questions [abp.io/faq](https://abp.io/faq). |
|||
|
|||
> Start your new ABP project -for free- 👉[abp.io/get-started](https://abp.io/get-started)! |
|||
|
|||
|
|||
### Join our community 👨👨👦 |
|||
We invite developers, IT professionals, and businesses to join the ABP Community. Our community website is now [abp.io/community](https://abp.io/community). On this website, you can read ABP-related posts, watch live community shows and core team's fundamental video courses... |
|||
|
|||
------ |
|||
|
|||
For more information, visit our newly unified platform at [abp.io](https://abp.io). We look forward to your feedback and continued support as we grow together! |
|||
|
|||
> Found a bug in the new platform? Or if you have an idea, write to us 👉 [abp.io/contact](https://abp.io/contact). |
|||
|
After Width: | Height: | Size: 238 KiB |
@ -0,0 +1,81 @@ |
|||
# Introducing the New ABP CLI |
|||
|
|||
 |
|||
|
|||
📢 We're excited to introduce the [new ABP CLI](https://abp.io/docs/latest/cli/index) after the announcement of [the new unified ABP Platform](https://abp.io/blog/new-abp-platform-is-live). |
|||
|
|||
As you know, we recently unified the ABP platform in a single domain ([abp.io](https://abp.io/)) and made some changes in our templating system to simplify your development. Also, we released more stable ABP Studio versions, which can dramatically improve and speed up your development time. Besides all of these changes, we have also introduced a new ABP CLI to bring you a more streamlined and efficient experience, which also extends the current commands. |
|||
|
|||
Here is a brief overview of what's new, what's changed, and why this change is happening... |
|||
|
|||
## The New ABP CLI |
|||
|
|||
ABP CLI is a command line tool to perform some common operations for ABP based solutions or [ABP Studio](https://abp.io/docs/latest/studio) features. With v8.2+, the old/legacy ABP CLI has been replaced with a new CLI system to align with the new templating system and ABP Studio. |
|||
|
|||
The new ABP CLI extends the old ABP CLI, adds more features that are used by ABP Studio behind the scenes, and is also fully compatible with the new templating system. Also, it allows you to use the old ABP CLI if you need, it by passing a single parameter. |
|||
|
|||
To be able to use the new ABP CLI, you should first delete the existing/old CLI with the following command if you installed it before: |
|||
|
|||
```bash |
|||
dotnet tool uninstall -g Volo.Abp.Cli |
|||
``` |
|||
|
|||
Then, to install the new ABP CLI, you can just simply execute the following command in your terminal: |
|||
|
|||
```bash |
|||
dotnet tool install -g Volo.Abp.Studio.Cli |
|||
``` |
|||
|
|||
> Both old and new ABP CLI binary names use the same `abp` command as the executing command. Therefore, you should uninstall the old CLI first, if you installed it before. |
|||
|
|||
> **Note**: Since the new ABP CLI uses the same `abp` command, you can use the same commands as you did before. |
|||
|
|||
## Reason for the Change |
|||
|
|||
ABP introduces a new templating system, which is fully compatible with the ABP Studio from v8.2+. Since, ABP Studio offers more and better features (such as tracking, monitoring, and deploying your applications from a single point), and the new templating system has a different versioning structure, we wanted to introduce a new ABP CLI by extending the current features and adding even more features that are compatible with the new templating system and ABP Studio. |
|||
|
|||
This change allows you to create your application with the new templating system either by running the cross-platform ABP Studio application or ABP CLI and allows you to create automated pipelines with the power of the new ABP CLI. |
|||
|
|||
## Using the Old ABP CLI |
|||
|
|||
If you have an older version of ABP solutions and need to use the old ABP CLI for any reason, you can do it easily with the new ABP CLI. |
|||
|
|||
You just need to put the `--old` command at the end of your command and execute the related CLI command as you would before. This allows you to use the old CLI commands with the new CLI without the need to uninstall the new CLI. |
|||
|
|||
For example, if you want to create a new ABP v8.2.0 solution, you can execute the following command: |
|||
|
|||
```bash |
|||
abp new Acme.BookStore --version 8.2.0 --old |
|||
``` |
|||
|
|||
When you run this command, the new ABP CLI installs the old CLI with `abp-old` name as the executing command within the latest version of ABP under the **%UserProfile%\\.abp\studio\cli\old** directory and allows you to use the old commands. |
|||
|
|||
If you want to use a specific version of the old ABP CLI, it's also possible with the new ABP CLI. You can use the `install-old-cli` command of the new CLI to either install or update an old CLI, then you can directly execute any old ABP CLI command by simply passing the `--old` parameter to the end of your command: |
|||
|
|||
```bash |
|||
# installing the old ABP CLI with v8.0 |
|||
abp install-old-cli --version 8.0.0 |
|||
|
|||
abp new Acme.BookStore --version 8.0 --old # alternatively, you can use the `abp-old` command without need to pass the "--old" parameter |
|||
``` |
|||
|
|||
## New Commands |
|||
|
|||
New ABP CLI extends the existing features of old ABP CLI and introduces new commands. Here are some of the new commands: |
|||
|
|||
* `kube-connect`: Connects to Kubernetes environment. (Available for **Business or higher licenses**) |
|||
* `kube-intercept`: Intercepts a service running in Kubernetes environment. (Available for **Business or higher licenses**) |
|||
* `list-module-sources`: Lists the remote module sources. |
|||
* and more... |
|||
|
|||
You can check the CLI documentation for all available commands and their usage. |
|||
|
|||
## Conclusion |
|||
|
|||
In this blog post, we briefly explained the new ABP CLI, what's the reason for this change, and how to use the old ABP CLI with the new ABP CLI. |
|||
|
|||
If you have any further questions related to the new ABP CLI, you can always refer to the [CLI](https://abp.io/docs/latest/cli/index) and [Old ABP CLI vs New ABP CLI](https://abp.io/docs/latest/cli/differences-between-old-and-new-cli) documentation. Also, we listed some of the questions that you may have, which you can [check from here](https://abp.io/docs/latest/cli/differences-between-old-and-new-cli#common-questions). |
|||
|
|||
Please try out the new ABP CLI, and provide feedback to help us release more stable versions, with additional features. |
|||
|
|||
Thanks for being a part of the ABP Community! |
|||
|
After Width: | Height: | Size: 19 KiB |
|
After Width: | Height: | Size: 34 KiB |
|
After Width: | Height: | Size: 39 KiB |
|
After Width: | Height: | Size: 44 KiB |
|
After Width: | Height: | Size: 134 KiB |
|
After Width: | Height: | Size: 28 KiB |
|
After Width: | Height: | Size: 105 KiB |
|
After Width: | Height: | Size: 5.5 KiB |
@ -0,0 +1,111 @@ |
|||
# Announcing ABP Studio (beta) General Availability |
|||
|
|||
ABP Framework makes your daily coding activities much easier, more convenient, and even more enjoyable. However, building a software product is not just about coding. We know that you need to build, run, test, debug and deploy your software, and trace errors on a failure. You also should to design architecture of your overall solution and perform many common operations on your solutions in addition to the coding activity. |
|||
|
|||
We'd already provided tools like [ABP CLI](https://abp.io/cli) and [ABP Suite](https://abp.io/suite) for these kind of purposes before. [ABP Studio](https://abp.io/studio) takes this one long step further and offers a tool that you can use continuously throughout your coding activities, help you for non-coding activities to make you focus on your software development. |
|||
|
|||
I am very excited to announce that the ABP Studio (beta) is generally available to everyone. It is now downloadable on the [get started page](https://abp.io/get-started) of the [new ABP Platform website](https://abp.io/blog/new-abp-platform-is-live). |
|||
|
|||
## What is ABP Studio? |
|||
|
|||
[ABP Studio](https://abp.io/docs/latest/studio) is a cross-platform desktop application for ABP and .NET developers. It aims to provide a comfortable development environment for you by automating things, providing insights about your solution, making develop, run, browse, monitor, trace and deploy your solutions much easier. |
|||
|
|||
**From now on, ABP Studio is the default way to start with the ABP Platform**; |
|||
|
|||
* The [get started page](https://abp.io/get-started) has updated so it offers to download ABP Studio to create a new ABP based solution. |
|||
* The ABP CLI ([Volo.Abp.Cli](https://nuget.org/packages/Volo.Abp.Cli)) is replaced by the ABP Studio CLI ([Volo.Abp.Studio.Cli](https://www.nuget.org/packages/Volo.Abp.Studio.Cli)). [The new ABP Studio CLI](https://abp.io/docs/latest/cli) is compatible with the old one, and extends it by introducing new commands. |
|||
* [Startup solution templates](https://abp.io/docs/latest/solution-templates) are completely renewed. The solution structures are similar to the old ones, but they are totally new templates built with the new templating engine. |
|||
* All the documentation and tutorials now uses ABP Studio and ABP Studio CLI. |
|||
|
|||
> **ABP Studio is in beta stage now.** It is also in rapid development and release cycle. We frequently release new feature and patch versions. Please [file an issue](https://github.com/abpframework/abp/issues/new/choose) if you have any problem. |
|||
> |
|||
> If you want to continue to use the old CLI and old startup templates, please [refer that document](https://abp.io/docs/latest/cli/differences-between-old-and-new-cli). |
|||
|
|||
## The Easiest Way to Start with the ABP Framework |
|||
|
|||
As mentioned before, the [startup solution templates](https://abp.io/docs/latest/solution-templates) are completely renewed with ABP Studio. They provide much more options compared to the old startup templates. The following screenshot is taken from the New Solution wizard of ABP Studio, which provides an comfortable and easy way to create new solutions: |
|||
|
|||
 |
|||
|
|||
For example, you can now select most of the non-fundamental modules as optional while creating a new solution: |
|||
|
|||
 |
|||
|
|||
### Developing Microservices Solutions is Now Much Easier |
|||
|
|||
The most important change is made on the [microservice startup template](https://abp.io/docs/latest/solution-templates/microservice) (which is available only for Business or higher license holders). We've designed the solution structure, integrations, Kubernetes/Helm configuration, database migrations and all others from scratch and well documented all the decisions we've applied. Developing microservice solutions with ABP Framework is now easier and more understandable than ever. |
|||
|
|||
## Architecting Your Complex Solutions |
|||
|
|||
One of the main purposes to build ABP Studio was to simplify to create multi-modular and distributed systems. Either you create a modular monolith application or a microservice solution, [ABP Studio's solution explorer](https://abp.io/docs/latest/studio/solution-explorer) provides a convenient way to design your high-level solution structure. |
|||
|
|||
You see a microservice solution in the following screenshot: |
|||
|
|||
 |
|||
|
|||
That ABP Studio solution contains multiple separate .NET solutions (`.sln`) each has multiple .NET projects (`.csproj`). ABP Studio allows you to easily manage such a multi-solution system on a single view. You can create new packages and modules, import existing packages and modules, manage their dependencies and so on. |
|||
|
|||
## Run and Test Your Multi-Application Solutions with a Single Click |
|||
|
|||
One of the biggest shortcomings we face when developing distributed or complex solutions is being able to easily run all components of the solutions so that we can test and debug a single service or application without caring about all the runtime dependencies. |
|||
|
|||
Here a screenshot from the ABP Studio's [Solution Runner](https://abp.io/docs/latest/studio/running-applications) view: |
|||
|
|||
 |
|||
|
|||
When you use ABP Studio, it is dramatically easier to run, monitor, test, debug and develop your applications and services. You can browse your web UI applications, monitor all the HTTP requests, distributed events, exceptions and logs in real time on a single screen. In this way, you can easily run all the systems and trace the problems when you have. |
|||
|
|||
All you need to click the *Play* button or right-click and select the *Run* -> *Start All* command: |
|||
|
|||
 |
|||
|
|||
The nice thing is that you can create multiple profiles for each of your teams so that they can run only the applications they need to develop the application they are working on. |
|||
|
|||
## Seamlessly Develop Your Service as Integrated to Kubernetes |
|||
|
|||
Kubernetes is the de-facto tool to deploy, run and scale complex systems. However, it can also be a great tool to develop such solutions in a local environment. |
|||
|
|||
With ABP Studio's [Kubernetes Integration](https://abp.io/docs/latest/studio/kubernetes) system, it is now possible to deploy and run a complex system in a Kubernetes cluster. Then you can establish a bridge between your local development environment and the Kubernetes cluster. In this way, you can develop, run, test and debug an application or service in your local development environment as it is running in the Kubernetes cluster. All incoming and outgoing traffic is properly routed and managed by ABP Studio. You just focus on the service you are responsible to develop and let the Kubernetes run rest of the system for you. |
|||
|
|||
You can see all the Helm charts in a solution in the Kubernetes panel of ABP Studio: |
|||
|
|||
 |
|||
|
|||
Here, you can easily build, install and uninstall the Helm charts to your Kubernetes cluster. In the Kubernetes tab, you can connect to the Kubernetes cluster and intercept a service to develop it locally. See [the documentation](https://abp.io/docs/latest/studio/kubernetes) for more information. |
|||
|
|||
The good news is that all the monitoring data (HTTP Requests, Events, Exceptions, Logs,...) is still visible in real time with the Kubernetes integration too. |
|||
|
|||
## Use the ABP Suite as Integrated to ABP Studio |
|||
|
|||
[ABP Suite](https://abp.io/suite) is a tool that is basically used to generate code for ABP Solutions. It has started by creating simple CRUD pages, and now it does much more. It can establish relations with existing entities, create complex user interfaces like parent/child tables and so on... |
|||
|
|||
ABP Suite can be used directly inside ABP Studio by clicking the *ABP Suite* -> *Open* command: |
|||
|
|||
 |
|||
|
|||
This will open ABP Suite in a new tab for the current solution and focus on the CRUD page generation: |
|||
|
|||
 |
|||
|
|||
The new ABP Studio solution templates and ABP Suite code generation are compatible with each other. Here a screenshot from the generated CRUD UI for a very simple Book entity: |
|||
|
|||
 |
|||
|
|||
## The Community Edition vs Commercial Licenses |
|||
|
|||
ABP Studio has a Community Edition which is completely free and available to everyone. As you can guess, there are come differences between the community edition and commercial editions. ABP Platform has 4 fundamental license types; |
|||
|
|||
* Open source (free) |
|||
* Team |
|||
* Business |
|||
* Enterprise |
|||
|
|||
Here, the comparison table for ABP Studio features for these license types: |
|||
|
|||
 |
|||
|
|||
Microservice startup template and Kubernetes integration features are available only for commercial licenses since these are considered more enterprise requirements. Also, the solution size is limited with the ABP Community edition. If you are building a large or distributed solution, consider to [purchase a commercial license](https://abp.io/pricing). |
|||
|
|||
## Conclusion |
|||
|
|||
I've introduced the ABP Studio General Availability with this post. It is still in the beta stage. You can expect frequent releases during the beta phase. We will add new features and fix issues quickly. Please [download](https://abp.io/studio) and use it now. If you find any problem, do not hesitate to open an [issue on GitHub](https://github.com/abpframework/abp/issues/new/choose). |
|||
|
After Width: | Height: | Size: 103 KiB |
|
After Width: | Height: | Size: 36 KiB |
|
After Width: | Height: | Size: 46 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 5.7 KiB |
|
After Width: | Height: | Size: 6.9 MiB |
|
After Width: | Height: | Size: 335 KiB |
|
After Width: | Height: | Size: 84 KiB |
|
After Width: | Height: | Size: 166 KiB |
|
After Width: | Height: | Size: 238 KiB |
|
After Width: | Height: | Size: 342 KiB |
@ -0,0 +1,177 @@ |
|||
# ABP Platform 8.3 RC Has Been Released |
|||
|
|||
 |
|||
|
|||
Today, we are happy to release [ABP](https://abp.io) version **8.3 RC** (Release Candidate). This blog post introduces the new features and important changes in this new version. |
|||
|
|||
Try this version and provide feedback for a more stable version of ABP v8.3! Thanks to you in advance. |
|||
|
|||
## Get Started with the 8.3 RC |
|||
|
|||
You can check the [Get Started page](https://abp.io/get-started) to see how to get started with ABP. You can either download [ABP Studio](https://abp.io/get-started#abp-studio-tab) (**recommended**, if you prefer a user-friendly GUI application - desktop application) or use the [ABP CLI](https://abp.io/docs/latest/cli). |
|||
|
|||
By default, ABP Studio uses stable versions to create solutions. Therefore, if you want to create a solution with a preview version, first you need to create a solution and then switch your solution to the preview version from the ABP Studio UI: |
|||
|
|||
 |
|||
|
|||
## Migration Guide |
|||
|
|||
There are a few breaking changes in this version that may affect your application. Please read the migration guide carefully, if you are upgrading from v8.2 or earlier: [ABP Version 8.3 Migration Guide](https://abp.io/docs/8.3/release-info/migration-guides/abp-8-3) |
|||
|
|||
## What's New with ABP v8.3? |
|||
|
|||
In this section, I will introduce some major features released in this version. |
|||
Here is a brief list of titles explained in the next sections: |
|||
|
|||
* CMS Kit: Marked Items/Favorites |
|||
* CMS Kit: Approvement System for Comments |
|||
* Docs: Added Google Translation Support & Introducing the Single Project Mode |
|||
* Using DBFunction for Global Query Filters |
|||
* CMS Kit (PRO): FAQ |
|||
* Package Updates (NuGet & NPM) |
|||
|
|||
### CMS Kit: Marked Items/Favorites |
|||
|
|||
CMS Kit provides a marking system to mark any kind of resource, like a blog post or a product, as a favorite, starred, flagged, or bookmarked. |
|||
|
|||
 |
|||
|
|||
This system is especially useful if you need to highlight some resources and differentiate them from other items. To use the marking system, you need to define an entity type with the icon name, by configuring the `CmsKitMarkedItemOptions`: |
|||
|
|||
```csharp |
|||
Configure<CmsKitMarkedItemOptions>(options => |
|||
{ |
|||
options.EntityTypes.Add( |
|||
new MarkedItemEntityTypeDefinition( |
|||
entityType: "product", |
|||
icon: StandardMarkedItems.Favorite |
|||
) |
|||
); |
|||
}); |
|||
``` |
|||
|
|||
You can select any of the standard marked item icons (as used in the example above) or easily customize the icons shown in the toggling components. |
|||
|
|||
> Read the [CMS Kit: Marked Item System](https://abp.io/docs/8.3/modules/cms-kit/marked-items) documentation to learn more. |
|||
|
|||
### CMS Kit: Approvement System for Comments |
|||
|
|||
CMS Kit Module has been provided a [Commenting System](https://abp.io/docs/8.3/modules/cms-kit/comments) for a while. This system allows you to add the comment feature to any kind of resource, like blog posts, or products. However, this system wasn't providing an approvement system, that allows system administrations to review the comments before publishing them in their application. |
|||
|
|||
In this version, we have introduced the [Approvement System](https://abp.io/docs/8.3/modules/cms-kit/comments#settings), which allows you to _require approval for comments to be published_. It's disabled by default, but you can make it enabled by simply checking the related setting on the settings page: |
|||
|
|||
 |
|||
|
|||
When you enable it, whenever a user submits a comment, it can be directly seen on the back-office application (in the _cms/comments_ page), and you can determine if the comment should be approved or rejected. If you approve the comment, then it will be shown in the comment section for the related resource. |
|||
|
|||
> Read the [CMS Kit: Comments](https://abp.io/docs/8.3/modules/cms-kit/comments) documentation to learn more. |
|||
|
|||
### Docs: Added Google Translation Support & Introducing the Single Project Mode |
|||
|
|||
In this version, we made some improvements in the [Docs Module](https://abp.io/docs/8.3/modules/docs), added Google Translation support for better findings in the documentation, and introduced a single project mode to align our needs in the documentation system with [the unification of the ABP Platform](https://abp.io/blog/new-abp-platform-is-live). |
|||
|
|||
The single project mode allows you to use a single name as a project name in your application. If you are not considering supporting multiple projects with their multiple docs and instead if you have a single project and want to have documentation for it, it's especially useful for you. You just need to configure the `DocsUiOptions`, set the single project mode as **enabled** and also define a constant project name: |
|||
|
|||
```csharp |
|||
Configure<DocsUiOptions>(options => |
|||
{ |
|||
options.SingleProjectMode.Enable = true; |
|||
options.SingleProjectMode.ProjectName = "abp"; |
|||
}); |
|||
``` |
|||
|
|||
In addition to this feature, we also introduced Google Translation support for the documentation system and even integrated it into our [abp.io/docs](https://abp.io/docs/) website: |
|||
|
|||
 |
|||
|
|||
 |
|||
|
|||
Thanks to this system, you can either translate your documentation into your own language by Google Translation System or search specific keywords to easily find the related topic in the documentation. |
|||
|
|||
### Using DBFunction for Global Query Filters |
|||
|
|||
In this version, ABP has started using [User-defined function mapping](https://learn.microsoft.com/en-us/ef/core/querying/user-defined-function-mapping) for global filters to gain performance improvements and let EF Core generate more precise SQL commands under the hook. |
|||
|
|||
> See the documentation for more info: [Using User-defined function mapping for global filters](https://abp.io/docs/8.3/framework/infrastructure/data-filtering#using-user-defined-function-mapping-for-global-filters) |
|||
|
|||
### CMS Kit: FAQ |
|||
|
|||
CMS Kit provides a [FAQ System](https://abp.io/docs/8.3/modules/cms-kit-pro/faq) to allow users to create, edit, and delete FAQs. Here is an example screenshot from the FAQ page on the admin side: |
|||
|
|||
 |
|||
|
|||
You can list, create, update, and delete sections and their questions on the admin side of your solution. Then, by using the `FaqViewComponent` in your public-web application, you can display FAQs, section by section: |
|||
|
|||
 |
|||
|
|||
> Read the [CMS Kit: FAQ System](https://abp.io/docs/8.3/modules/cms-kit-pro/faq) documentation to learn more. |
|||
|
|||
### Package Updates |
|||
|
|||
In this version, we also updated some of the core NuGet and NPM package versions. All of the removed or deprecated methods have already been updated at the framework level. However, if you used any methods from these packages, you should be aware of the change and update it in your code accordingly. |
|||
|
|||
You can see the following list of the package version changes: |
|||
|
|||
* [Updated Markdig.Signed from v0.33.0 to v0.37.0](https://github.com/abpframework/abp/pull/20195) - [NuGet](https://www.nuget.org/packages/Markdig.Signed) |
|||
* [Updated Hangfire from v1.8.6 to v1.8.12](https://github.com/abpframework/abp/pull/20009) - [NuGet](https://www.nuget.org/packages/Hangfire.AspNetCore) |
|||
* [Updated SixLabors.ImageSharp from v3.0.2 to v3.1.4](https://github.com/abpframework/abp/pull/19643) - [NuGet](https://www.nuget.org/packages/SixLabors.ImageSharp) |
|||
* [Updated Blazorise from v1.5.0 to v1.5.2](https://github.com/abpframework/abp/pull/19841) - [NuGet](https://www.nuget.org/packages/Blazorise) |
|||
* [Updated datatables.net from v1.11.4 to v2.0.2](https://github.com/abpframework/abp/pull/19340) - [NPM](https://www.npmjs.com/package/datatables.net) |
|||
|
|||
## Community News |
|||
|
|||
### The New ABP Platform Is Live! |
|||
|
|||
 |
|||
|
|||
We're thrilled to announce that the **new ABP.IO Platform** is now live! Our team has been hard at unifying and enhancing the entire platform to deliver a seamless, user-friendly experience. We consolidated all our services under a single domain: [abp.io](https://abp.io/); added a new mega menu that makes finding what you need much easier and faster, and also improved the UX of our application and combined both ABP (open-source) and ABP Commercial (paid) documents into a single comprehensive resource. |
|||
|
|||
> Read the blog post to learn more about this unification 👉 [The new ABP Platform is live!](https://abp.io/blog/new-abp-platform-is-live) |
|||
|
|||
### Announcing ABP Studio (Beta) General Availability |
|||
|
|||
We're really excited to announce that the **ABP Studio (beta)** is generally available to everyone. It is now downloadable on the [get started page](https://abp.io/get-started) of the [new ABP Platform website](https://abp.io/blog/new-abp-platform-is-live). |
|||
|
|||
 |
|||
|
|||
> Read the blog post to learn more about the ABP Studio (Beta) 👉 [Announcing ABP Studio (beta) General Availability](https://abp.io/blog/announcing-abp-studio-general-availability) |
|||
|
|||
### Introducing the New ABP CLI |
|||
|
|||
As described above, we recently [unified the ABP platform in a single domain (abp.io)](https://abp.io/blog/new-abp-platform-is-live) and made some changes in our templating system to simplify your development. Also, we released more stable **ABP Studio** versions, which can dramatically improve and speed up your development time. |
|||
|
|||
Besides all of these changes, we have also introduced a [new ABP CLI](https://abp.io/docs/latest/cli/index) to bring you a more streamlined and efficient experience, which also extends the current commands. |
|||
|
|||
 |
|||
|
|||
The new ABP CLI extends the old ABP CLI, adds more features that are used by ABP Studio behind the scenes, and is also fully compatible with the new templating system. We created a blog post, which you can read at [https://abp.io/blog/introducing-the-new-abp-cli](https://abp.io/blog/introducing-the-new-abp-cli) to highlight the reason behind this change and insights into the new ABP CLI, you can check it out if you want to learn more. |
|||
|
|||
### New ABP Community Articles |
|||
|
|||
There are exciting articles contributed by the ABP community as always. I will highlight some of them here: |
|||
|
|||
* [Ahmed Tarek](https://twitter.com/AhmedTarekHasa1) has created **three** new community articles: |
|||
* [🧪 Unit Testing Best Practices In .NET C# 🤷♂️](https://abp.io/community/articles/-unit-testing-best-practices-in-.net-c--mnx65npu) |
|||
* [Memory Management In .NET](https://abp.io/community/articles/memory-management-in-.net-rqwbtzvl) |
|||
* [🧵 How String In .NET C# Works 🤷♂️](https://abp.io/community/articles/-how-string-in-.net-c-works--vj6d2pnm) |
|||
|
|||
* [Anto Subash](https://twitter.com/antosubash) has created **two** new community videos: |
|||
* [ABP React Template V2](https://abp.io/community/videos/abp-react-template-v2-ilc4cyqr) |
|||
* [Migrating Tye to Aspire - .NET Microservice with ABP](https://abp.io/community/videos/migrating-tye-to-aspire-.net-microservice-with-abp-ga1t4ckr) |
|||
|
|||
* [HeadChannel Team](https://headchannel.co.uk/) has created **two** new community articles: |
|||
* [Managing Baseline Creation in Applications Based on ABP Framework](https://abp.io/community/articles/managing-baseline-creation-in-applications-based-on-abp-framework-yiacte5c) |
|||
* [How to Test The System Using PostgreSQL and TestContainers](https://abp.io/community/articles/how-to-test-the-system-using-postgresql-and-testcontainers-8yh8t0j8) |
|||
|
|||
* [Create a Generic HTTP Service to Consume a Web API](https://abp.io/community/articles/create-a-generic-http-service-to-consume-a-web-api-yidme2kq) by [Bart Van Hoey](https://github.com/bartvanhoey) |
|||
* [Use User-Defined Function Mapping for Global Filter](https://abp.io/community/articles/use-userdefined-function-mapping-for-global-filter-pht26l07) by [Liming Ma](https://github.com/maliming) |
|||
* [How to use .NET Aspire with ABP framework](https://abp.io/community/articles/how-to-use-.net-aspire-with-abp-framework-h29km4kk) by [Berkan Şaşmaz](https://twitter.com/berkansasmazz) |
|||
* [Exciting New Feature in ABP.IO CMS Kit: Marked Item System](https://abp.io/community/articles/exciting-new-feature-in-abp.io-cms-kit-marked-item-system.-2hvpq0me) by [Suhaib Mousa](https://abp.io/community/members/suhaibmousa032@gmail.com) |
|||
|
|||
Thanks to the ABP Community for all the content they have published. You can also [post your ABP-related (text or video) content](https://abp.io/community/posts/submit) to the ABP Community. |
|||
|
|||
## Conclusion |
|||
|
|||
This version comes with some new features and a lot of enhancements to the existing features. You can see the [Road Map](https://abp.io/docs/8.3/release-info/road-map) documentation to learn about the release schedule and planned features for the next releases. Please try ABP v8.3 RC and provide feedback to help us release a more stable version. |
|||
|
|||
Thanks for being a part of this community! |
|||
|
After Width: | Height: | Size: 1.0 MiB |
|
After Width: | Height: | Size: 34 KiB |
|
After Width: | Height: | Size: 16 KiB |
|
After Width: | Height: | Size: 47 KiB |
|
After Width: | Height: | Size: 70 KiB |
|
After Width: | Height: | Size: 76 KiB |
@ -0,0 +1,490 @@ |
|||
# Switching Between Organization Units |
|||
|
|||
In most companies, a user belongs to more than one organization. Also, in some applications, we need to filter the data shown depending on the logged-in user's organization. For such scenarios, allowing users to select one of the organizations they belong to is a good practice. |
|||
|
|||
 |
|||
|
|||
## Creating a Data Filter with Organization Units |
|||
|
|||
### IHasOrganization |
|||
|
|||
First, we need to create a data filter that filters data based on the organization unit. |
|||
|
|||
The `IHasOrganization` interface is used to define the organization unit property in the entity classes, and used to filter the data based on the organization unit. |
|||
|
|||
```csharp |
|||
public interface IHasOrganization |
|||
{ |
|||
public Guid? OrganizationId { get; set; } |
|||
} |
|||
``` |
|||
|
|||
```csharp |
|||
public class Book : AggregateRoot<Guid>, IHasOrganization |
|||
{ |
|||
public string Name { get; set; } |
|||
|
|||
public string Isbn { get; set; } |
|||
|
|||
public Guid? OrganizationId { get; set; } |
|||
} |
|||
``` |
|||
|
|||
### Entity Framework Core DbContext Implementation |
|||
|
|||
We will override the `ShouldFilterEntity` and `CreateFilterExpression` methods in the `BookStoreDbContext` class to configure the data filter for the entity that implements the `IHasOrganization` interface. |
|||
|
|||
```csharp |
|||
public class BookStoreDbContext : AbpDbContext<BookStoreDbContext> |
|||
{ |
|||
// Your others DbSet properties... |
|||
|
|||
public DbSet<Book> Books { get; set; } |
|||
|
|||
protected override void OnModelCreating(ModelBuilder builder) |
|||
{ |
|||
base.OnModelCreating(builder); |
|||
|
|||
// Your configure code... |
|||
|
|||
builder.Entity<Book>(b => |
|||
{ |
|||
b.ToTable(BookStoreConsts.DbTablePrefix + "Book", BookStoreConsts.DbSchema); |
|||
b.ConfigureByConvention(); |
|||
}); |
|||
} |
|||
|
|||
public CurrentOrganizationIdProvider CurrentOrganizationIdProvider => LazyServiceProvider.LazyGetRequiredService<CurrentOrganizationIdProvider>(); |
|||
|
|||
protected override bool ShouldFilterEntity<TEntity>(IMutableEntityType entityType) |
|||
{ |
|||
if (typeof(IHasOrganization).IsAssignableFrom(typeof(TEntity))) |
|||
{ |
|||
return true; |
|||
} |
|||
|
|||
return base.ShouldFilterEntity<TEntity>(entityType); |
|||
} |
|||
|
|||
protected override Expression<Func<TEntity, bool>> CreateFilterExpression<TEntity>(ModelBuilder modelBuilder) |
|||
{ |
|||
var expression = base.CreateFilterExpression<TEntity>(modelBuilder); |
|||
|
|||
if (typeof(IHasOrganization).IsAssignableFrom(typeof(TEntity))) |
|||
{ |
|||
Expression<Func<TEntity, bool>> hasOrganizationIdFilter = e => EF.Property<Guid>(e, "OrganizationId") == CurrentOrganizationIdProvider.CurrentOrganizationId; |
|||
expression = expression == null ? hasOrganizationIdFilter : QueryFilterExpressionHelper.CombineExpressions(expression, hasOrganizationIdFilter); |
|||
} |
|||
|
|||
return expression; |
|||
} |
|||
} |
|||
``` |
|||
|
|||
### The CurrentOrganizationIdProvider |
|||
|
|||
This class is used to get the current `organization id`, We will use the `AsyncLocal` class to store the current `organization id`, The `Change` method is used to change the current `organization id`. This service is registered as a singleton service. |
|||
|
|||
```csharp |
|||
public class CurrentOrganizationIdProvider : ISingletonDependency |
|||
{ |
|||
private readonly AsyncLocal<Guid?> _currentOrganizationId = new AsyncLocal<Guid?>(); |
|||
|
|||
public Guid? CurrentOrganizationId => _currentOrganizationId.Value; |
|||
|
|||
public virtual IDisposable Change(Guid? organizationId) |
|||
{ |
|||
var parent = CurrentOrganizationId; |
|||
_currentOrganizationId.Value = organizationId; |
|||
return new DisposeAction(() => |
|||
{ |
|||
_currentOrganizationId.Value = parent; |
|||
}); |
|||
} |
|||
} |
|||
``` |
|||
|
|||
## Domain Service Implementation |
|||
|
|||
We will store the current `organization id` in the cache for the logged-in user. at the same time, we want to store it per browser. So we also add the different browser info for every logged-in user. |
|||
|
|||
In the `BrowserInfoClaimsPrincipalContributor` class, We add a random `BrowserInfo` claim to the logged-in user. And we will use `user id` and `browser info `as a cache key. |
|||
|
|||
```csharp |
|||
public static class CurrentUserExtensions |
|||
{ |
|||
public static Guid? GetBrowserInfo(this ICurrentUser currentUser) |
|||
{ |
|||
var claimValue = currentUser.FindClaimValue("BrowserInfo"); |
|||
if (claimValue != null && Guid.TryParse(claimValue, out var result)) |
|||
{ |
|||
return result; |
|||
} |
|||
return null; |
|||
} |
|||
} |
|||
|
|||
public class BrowserInfoClaimsPrincipalContributor : IAbpClaimsPrincipalContributor, ITransientDependency |
|||
{ |
|||
public Task ContributeAsync(AbpClaimsPrincipalContributorContext context) |
|||
{ |
|||
var identity = context.ClaimsPrincipal.Identities.FirstOrDefault(); |
|||
identity?.AddClaim(new Claim("BrowserInfo", Guid.NewGuid().ToString())); |
|||
return Task.CompletedTask; |
|||
} |
|||
} |
|||
``` |
|||
|
|||
## Application Service Implementation |
|||
|
|||
The `CurrentOrganizationAppService` to get/change the current organization for the logged-in user. `BookAppService` to get the books based on the current `organization id`. |
|||
|
|||
```csharp |
|||
[Authorize] |
|||
public class CurrentOrganizationAppService : BookStoreAppService, ICurrentOrganizationAppService |
|||
{ |
|||
private readonly IdentityUserManager _identityUserManager; |
|||
private readonly IDistributedCache<CurrentOrganizationIdCacheItem> _cache; |
|||
|
|||
public CurrentOrganizationAppService(IdentityUserManager identityUserManager, IDistributedCache<CurrentOrganizationIdCacheItem> cache) |
|||
{ |
|||
_identityUserManager = identityUserManager; |
|||
_cache = cache; |
|||
} |
|||
|
|||
public virtual async Task<List<OrganizationDto>> GetOrganizationListAsync() |
|||
{ |
|||
var user = await _identityUserManager.FindByIdAsync(CurrentUser.GetId().ToString()); |
|||
var organizationUnits = await _identityUserManager.GetOrganizationUnitsAsync(user); |
|||
return organizationUnits.Select(ou => new OrganizationDto |
|||
{ |
|||
Id = ou.Id, |
|||
DisplayName = ou.DisplayName |
|||
}).ToList(); |
|||
} |
|||
|
|||
public virtual async Task<Guid?> GetCurrentOrganizationIdAsync() |
|||
{ |
|||
var cacheKey = CurrentUser.Id.ToString() + ":" + CurrentUser.GetBrowserInfo(); |
|||
return (await _cache.GetAsync(cacheKey))?.OrganizationId; |
|||
} |
|||
|
|||
public virtual async Task ChangeAsync(Guid? organizationId) |
|||
{ |
|||
var cacheKey = CurrentUser.Id.ToString() + ":" + CurrentUser.GetBrowserInfo(); |
|||
await _cache.SetAsync(cacheKey, new CurrentOrganizationIdCacheItem |
|||
{ |
|||
OrganizationId = organizationId |
|||
}); |
|||
} |
|||
} |
|||
``` |
|||
|
|||
```csharp |
|||
[Authorize] |
|||
public class BookAppService : BookStoreAppService, IBookAppService |
|||
{ |
|||
private readonly IBasicRepository<Book, Guid> _bookRepository; |
|||
|
|||
public BookAppService(IBasicRepository<Book, Guid> bookRepository) |
|||
{ |
|||
_bookRepository = bookRepository; |
|||
} |
|||
|
|||
public virtual async Task<List<BookDto>> GetListAsync() |
|||
{ |
|||
var books = await _bookRepository.GetListAsync(); |
|||
return books.Select(book => new BookDto |
|||
{ |
|||
Id = book.Id, |
|||
Name = book.Name, |
|||
Isbn = book.Isbn, |
|||
OrganizationId = book.OrganizationId |
|||
}).ToList(); |
|||
} |
|||
} |
|||
``` |
|||
|
|||
## Seed Sample Data |
|||
|
|||
Let's seed some sample data for the `Book` and `Organization` entities. |
|||
|
|||
We added two organization units, `USA Branch` and `Turkey Branch`, and some books to each organization unit. Also, we added the `admin` user to both organization units. |
|||
|
|||
```csharp |
|||
public class BooksDataSeedContributor : IDataSeedContributor, ITransientDependency |
|||
{ |
|||
public Guid UsaBranchId = Guid.Parse("00000000-0000-0000-0000-000000000001"); |
|||
public Guid TurkeyBranchId = Guid.Parse("00000000-0000-0000-0000-000000000002"); |
|||
|
|||
private readonly IBasicRepository<Book, Guid> _bookRepository; |
|||
private readonly OrganizationUnitManager _organizationUnitManager; |
|||
private readonly IOrganizationUnitRepository _organizationUnitRepository; |
|||
private readonly IdentityUserManager _identityUserManager; |
|||
private readonly IUnitOfWorkManager _unitOfWorkManager; |
|||
|
|||
public BooksDataSeedContributor( |
|||
IBasicRepository<Book, Guid> bookRepository, |
|||
OrganizationUnitManager organizationUnitManager, |
|||
IOrganizationUnitRepository organizationUnitRepository, |
|||
IdentityUserManager identityUserManager, |
|||
IUnitOfWorkManager unitOfWorkManager) |
|||
{ |
|||
_bookRepository = bookRepository; |
|||
_organizationUnitManager = organizationUnitManager; |
|||
_organizationUnitRepository = organizationUnitRepository; |
|||
_identityUserManager = identityUserManager; |
|||
_unitOfWorkManager = unitOfWorkManager; |
|||
} |
|||
|
|||
public virtual async Task SeedAsync(DataSeedContext context) |
|||
{ |
|||
using (var uow = _unitOfWorkManager.Begin()) |
|||
{ |
|||
var usa = await _organizationUnitRepository.FindAsync(UsaBranchId); |
|||
if (usa == null) |
|||
{ |
|||
await _organizationUnitManager.CreateAsync(new OrganizationUnit(UsaBranchId, "USA Branch")); |
|||
} |
|||
|
|||
var turkey = await _organizationUnitRepository.FindAsync(TurkeyBranchId); |
|||
if (turkey == null) |
|||
{ |
|||
await _organizationUnitManager.CreateAsync(new OrganizationUnit(TurkeyBranchId, "Turkey Branch")); |
|||
} |
|||
|
|||
await uow.SaveChangesAsync(); |
|||
|
|||
var admin = await _identityUserManager.FindByNameAsync("admin"); |
|||
Check.NotNull(admin, "admin"); |
|||
|
|||
await _identityUserManager.AddToOrganizationUnitAsync(admin.Id, UsaBranchId); |
|||
await _identityUserManager.AddToOrganizationUnitAsync(admin.Id, TurkeyBranchId); |
|||
|
|||
if (await _bookRepository.GetCountAsync() <= 0) |
|||
{ |
|||
await _bookRepository.InsertAsync(new Book |
|||
{ |
|||
Name = "1984", |
|||
Isbn = "978-0451524935", |
|||
OrganizationId = UsaBranchId |
|||
}); |
|||
|
|||
await _bookRepository.InsertAsync(new Book |
|||
{ |
|||
Name = "Animal Farm", |
|||
Isbn = "978-0451526342", |
|||
OrganizationId = UsaBranchId |
|||
}); |
|||
|
|||
await _bookRepository.InsertAsync(new Book |
|||
{ |
|||
Name = "Brave New World", |
|||
Isbn = "978-0060850524", |
|||
OrganizationId = UsaBranchId |
|||
}); |
|||
|
|||
await _bookRepository.InsertAsync(new Book |
|||
{ |
|||
Name = "Fahrenheit 451", |
|||
Isbn = "978-1451673319", |
|||
OrganizationId = TurkeyBranchId |
|||
}); |
|||
|
|||
await _bookRepository.InsertAsync(new Book |
|||
{ |
|||
Name = "The Catcher in the Rye", |
|||
Isbn = "978-0316769488", |
|||
OrganizationId = TurkeyBranchId |
|||
}); |
|||
|
|||
await _bookRepository.InsertAsync(new Book |
|||
{ |
|||
Name = "To Kill a Mockingbird", |
|||
Isbn = "978-0061120084", |
|||
OrganizationId = TurkeyBranchId |
|||
}); |
|||
} |
|||
|
|||
await uow.CompleteAsync(); |
|||
} |
|||
} |
|||
} |
|||
``` |
|||
|
|||
## Web Page Implementation |
|||
|
|||
We will add a dropdown list to the top right corner of the page to allow users to select the organization they belong to. When the dropdown list changes, we will call the application service api to change the current `organization id`. |
|||
|
|||
```csharp |
|||
public class OrganizationUnitComponent : AbpViewComponent |
|||
{ |
|||
public async Task<IViewComponentResult> InvokeAsync() |
|||
{ |
|||
var currentOrganizationAppService = LazyServiceProvider.GetRequiredService<ICurrentOrganizationAppService>(); |
|||
var organizationDtos = await currentOrganizationAppService.GetOrganizationListAsync(); |
|||
var currentOrganizationId = await currentOrganizationAppService.GetCurrentOrganizationIdAsync(); |
|||
return View("/Components/OrganizationUnits/Default.cshtml", new OrganizationUnitComponentModel |
|||
{ |
|||
CurrentOrganizationId = currentOrganizationId, |
|||
OrganizationDtos = organizationDtos |
|||
}); |
|||
} |
|||
} |
|||
|
|||
public class OrganizationUnitComponentModel |
|||
{ |
|||
public Guid? CurrentOrganizationId { get; set; } |
|||
|
|||
public List<OrganizationDto> OrganizationDtos { get; set; } |
|||
} |
|||
``` |
|||
|
|||
```html |
|||
@using Microsoft.AspNetCore.Mvc.TagHelpers |
|||
@using Volo.Abp.AspNetCore.Mvc.UI.Bundling.TagHelpers |
|||
@model BookStore.Web.Components.OrganizationUnits.OrganizationUnitComponentModel |
|||
|
|||
<div class="dropstart"> |
|||
<a href="#" class="btn mt-2" data-bs-toggle="dropdown" type="button"> |
|||
<i class="fa fa-city m-auto"></i> |
|||
</a> |
|||
<ul class="dropdown-menu p-0" style="width: 200px"> |
|||
<div class="list-group"> |
|||
@foreach (var ou in Model.OrganizationDtos) |
|||
{ |
|||
<button type="button" onclick="setOrganizationUnitId('@ou.Id')" class="list-group-item list-group-item-action @(ou.Id == Model.CurrentOrganizationId ? "active" : "")">@ou.DisplayName</button> |
|||
} |
|||
</div> |
|||
</ul> |
|||
</div> |
|||
|
|||
<script> |
|||
function setOrganizationUnitId(id) { |
|||
bookStore.currentOrganization.currentOrganization.change(id).then(function () { |
|||
location.reload(); |
|||
}); |
|||
} |
|||
</script> |
|||
``` |
|||
|
|||
Add the `OrganizationUnitComponent` to the toolbar. |
|||
|
|||
```csharp |
|||
public class BookStoreToolbarContributor : IToolbarContributor |
|||
{ |
|||
public virtual Task ConfigureToolbarAsync(IToolbarConfigurationContext context) |
|||
{ |
|||
// ... |
|||
|
|||
if (context.Toolbar.Name == StandardToolbars.Main) |
|||
{ |
|||
context.Toolbar.Items.Add(new ToolbarItem(typeof(OrganizationUnitComponent)).RequireAuthenticated()); |
|||
} |
|||
|
|||
return Task.CompletedTask; |
|||
} |
|||
} |
|||
``` |
|||
|
|||
In addition, we also need to add a middleware after `UseAuthorization` to change the current `organization id`. |
|||
|
|||
```csharp |
|||
app.UseAuthorization(); |
|||
app.Use(async (httpContext, next) => |
|||
{ |
|||
var currentUser = httpContext.RequestServices.GetRequiredService<ICurrentUser>(); |
|||
var cacheKey = currentUser.Id.ToString() + ":" + currentUser.GetBrowserInfo(); |
|||
var cache = httpContext.RequestServices.GetRequiredService<IDistributedCache<CurrentOrganizationIdCacheItem>>(); |
|||
var cacheItem = await cache.GetAsync(cacheKey); |
|||
if (cacheItem != null) |
|||
{ |
|||
var currentOrganizationIdProvider = httpContext.RequestServices.GetRequiredService<CurrentOrganizationIdProvider>(); |
|||
currentOrganizationIdProvider.Change(cacheItem.OrganizationId); |
|||
} |
|||
await next(httpContext); |
|||
}); |
|||
// ... |
|||
``` |
|||
|
|||
The `Index` page will show the books based on the current `organization id`. |
|||
|
|||
```cshtml |
|||
public class IndexModel : BookStorePageModel |
|||
{ |
|||
public List<BookDto> Books { get; set; } = new List<BookDto>(); |
|||
public string? OrganizationName { get; set; } |
|||
|
|||
protected readonly IBookAppService BookAppService; |
|||
protected readonly ICurrentOrganizationAppService CurrentOrganizationAppService; |
|||
protected readonly IOrganizationUnitRepository OrganizationUnitRepository; |
|||
|
|||
public IndexModel( |
|||
IBookAppService bookAppService, |
|||
ICurrentOrganizationAppService currentOrganizationAppService, |
|||
IOrganizationUnitRepository organizationUnitRepository) |
|||
{ |
|||
BookAppService = bookAppService; |
|||
CurrentOrganizationAppService = currentOrganizationAppService; |
|||
OrganizationUnitRepository = organizationUnitRepository; |
|||
} |
|||
|
|||
public async Task OnGetAsync() |
|||
{ |
|||
if (CurrentUser.IsAuthenticated) |
|||
{ |
|||
var currentOrganizationId = await CurrentOrganizationAppService.GetCurrentOrganizationIdAsync(); |
|||
if (currentOrganizationId.HasValue) |
|||
{ |
|||
OrganizationName = (await OrganizationUnitRepository.GetAsync(currentOrganizationId.Value)).DisplayName; |
|||
} |
|||
|
|||
Books = await BookAppService.GetListAsync(); |
|||
} |
|||
} |
|||
} |
|||
``` |
|||
|
|||
```html |
|||
@page |
|||
@model BookStore.Web.Pages.IndexModel |
|||
@using Microsoft.AspNetCore.Mvc.Localization |
|||
@using BookStore.Localization |
|||
@inject IHtmlLocalizer<BookStoreResource> L |
|||
|
|||
@if (!Model.OrganizationName.IsNullOrEmpty()) |
|||
{ |
|||
<h5>The books belonging to @Model.OrganizationName organization</h5> |
|||
} |
|||
|
|||
<ul class="list-group"> |
|||
@foreach(var book in Model.Books) |
|||
{ |
|||
<li class="list-group-item">Book Name: @book.Name, ISBN: @book.Isbn</li> |
|||
} |
|||
</ul> |
|||
``` |
|||
|
|||
### Final UI |
|||
|
|||
The final UI will look like this: |
|||
|
|||
The index page will show empty if the current organization id is not set. |
|||
After selecting the organization unit, the index page will show the books based on the selected organization unit. |
|||
|
|||
 |
|||
|
|||
 |
|||
|
|||
 |
|||
|
|||
## Summary |
|||
|
|||
In this blog post. We showd simple implementation of switching between organization units. You can extend this implementation to meet your requirements. |
|||
|
|||
After [ABP 8.3](https://github.com/abpframework/abp/pull/20065) we introduced [User-defined function mapping](https://learn.microsoft.com/en-us/ef/core/querying/user-defined-function-mapping) feature for global filters which will gain performance improvements. |
|||
|
|||
## References |
|||
|
|||
- [Data Filtering](https://abp.io/docs/latest/framework/infrastructure/data-filtering) |
|||
- [Claims Principal Factory](https://abp.io/docs/latest/framework/fundamentals/authorization#claims-principal-factory) |
|||
|
After Width: | Height: | Size: 261 KiB |
@ -0,0 +1,78 @@ |
|||
# New ABP Documentation System: Everything You Need In One Place 📣 |
|||
|
|||
We have combined the ABP (open-source) and ABP Commercial (paid) documents into a single, comprehensive resource. This unification brings you a better experience in the documentation system, helps you find what you're looking for more easily, allows you to read the documents that are related to each other one after the other, and also provides Google Search and Google Translation support for the documents. |
|||
|
|||
 |
|||
|
|||
Let's see what's new with the unified documentation system in detail: |
|||
|
|||
## All Documentation In One Place 📃 |
|||
|
|||
We decided to combine the ABP (open-source) and ABP Commercial (paid) documents into a single place, along with [the new ABP Platform Unification](https://abp.io/blog/new-abp-platform-is-live). |
|||
|
|||
The new documentation address is [abp.io/docs](https://abp.io/docs) and seen like below: |
|||
|
|||
 |
|||
|
|||
This unified documentation brings you a better search capability with Google Search support, allows you to not need to switch between documentation websites to read both framework and commercial features, look what you are looking for more easily from the unified menu structure, following new features and their documentation in a more stable and easier way. |
|||
|
|||
## Accessing Documents with Older Versions🗃️ |
|||
|
|||
From v8.2, with the new documentation system, since we merged all documents into a single place, you don't need to select if you want to show a framework or commercial document. However, if you want to access an old document, for example, if you are using an older version of ABP or don't want to create the solutions from ABP Studio and instead prefer ABP CLI (in the getting started and startup template docs, ABP Studio is shown for project creation and other features, for instance), you can change the version from the version select-box (prior to v8.2), and select which document type (framework or commercial) you want to read and then find/choose the document that you want: |
|||
|
|||
 |
|||
|
|||
You can access any old-version document as you would before, by specifying the version. But we suggest you update your solution to v8.2+ and start using ABP Studio! By doing that, you can get more benefits from the new features, and edge-cutting features of ABP Studio and easily manage your application from development to production! |
|||
|
|||
## Documentation Updates 🚀 |
|||
|
|||
With the [announcement of ABP Studio (beta) General Availability](https://abp.io/blog/announcing-abp-studio-general-availability), we made some improvements in our documents. Starting from v8.2, since ABP Studio is the suggested way to create and manage your applications, we updated the [Get started](https://abp.io/docs/latest/get-started) documentation and some other documents along with, and explained project creation via ABP Studio. If you prefer [creating a new solution with the ABP CLI](https://abp.io/docs/latest/cli), you can use the new ABP CLI as you did the old one before. |
|||
|
|||
Besides that, we revised all of our documents, updated most of them according to the [new ABP Platform unification](https://abp.io/blog/new-abp-platform-is-live). For example, we merged our migration guide documents into single documents for each version and categorized the related topics you need to do when updating your solutions under the **open-source** and **pro** sections, so either you are an open-source template user or a license owner, you can easily jump to the related section and read them easily and accordingly: |
|||
|
|||
 |
|||
|
|||
Since we combined ABP (framework) and ABP Commercial documents, we added information notes in each document that indicate if the related feature is in your license plan or not. An example screenshot from ABP Suite documentation can be seen as follow: |
|||
|
|||
 |
|||
|
|||
Also, for the application modules, we added **(PRO)** postfixes in the navigation menu for you to easily understand if the module is for license owners or open-source users. Thanks to that you can easily distinguish the related application modules and read the related module documentation to understand it: |
|||
|
|||
 |
|||
|
|||
|
|||
## New Navigation Tree 📚 |
|||
|
|||
With the documentation unification, we re-structured the navigation tree of the documents: |
|||
|
|||
 |
|||
|
|||
The new navigation tree allows you to find any document you want in a more desired way, in the related sub-menu. For example, if you want to learn more about *modularity*, you can find under the **Framework > Architecture > Modularity** menu items, or if you want to learn more about the ABP Studio, you can find the all related docs under the root **Tools** menu. |
|||
|
|||
## Google Translate & Search Capabilities 🔎 |
|||
|
|||
In ABP v8.3, we made some improvements in the [Docs Module](https://abp.io/docs/8.3/modules/docs), added Google Search support for better findings in the documentation, and introduced Google Translation for the documentation system. After implementing these features, we integrated them into our documentation system and removed the languages select box from the menu: |
|||
|
|||
 |
|||
|
|||
From now on, we will provide documents in English only. The reason behind that is, that with the new Google Translate support, you can directly translate any documentation to the desired language (of course, must be one of the supported languages). Thanks to the Google Translate feature, you can read the official documentation in your own language, and we as the core team, don't need to synchronize the documentation between different languages, it was really hard to keep them up to date, and now they all will be available all the time in the all supported languages. |
|||
|
|||
 |
|||
|
|||
Also, thanks to Google Search, now you can search specific keywords to easily find the related topic in the documentation. For example, if you search the **Validation** keyword, Google will list all related documents according to their importance and relevancy: |
|||
|
|||
## Feedbacks 📝 |
|||
|
|||
Besides all changes, we also added a **feedback section** at the end of each document. You can share your thoughts, suggestions, or criticism for specific documentation. We would like to hear more from you about our documentation quality and get suggestions from each one of you to improve our documents and platform, so it will be much appreciated if you share your feedback for any documentation you want, please don't hesitate! |
|||
|
|||
 |
|||
|
|||
You can either directly scroll down to the bottom directly for a certain document, or click the **Feedback** action button to navigate to the feedbacks section, and provide feedback: |
|||
|
|||
 |
|||
|
|||
## Conclusion 🎯 |
|||
|
|||
To see the new ABP documentation system, please visit the [abp.io/docs](https://abp.io/docs/latest/) website. Check out the new navigation tree, read the documents you want, provide feedback to help us improve our documents, and more... |
|||
|
|||
We look forward to your feedback and continued support as we grow together! Thanks in advance 🙏 |
|||
|
After Width: | Height: | Size: 294 KiB |