diff --git a/docs/en/Community-Articles/2021-06-17-Using-Elsa-Workflow-with-ABP-Framework/POST.md b/docs/en/Community-Articles/2021-06-17-Using-Elsa-Workflow-with-ABP-Framework/POST.md index 81be9e52a5..21779c3745 100644 --- a/docs/en/Community-Articles/2021-06-17-Using-Elsa-Workflow-with-ABP-Framework/POST.md +++ b/docs/en/Community-Articles/2021-06-17-Using-Elsa-Workflow-with-ABP-Framework/POST.md @@ -1,6 +1,6 @@ # Using Elsa Workflow with ABP Framework -**Elsa Core** is an open-source workflows library that can be used in any kind of .NET Core application. Using such a workflow library can be useful to implement a business rules visually or programmatically. +**Elsa Core** is an open-source workflows library that can be used in any kind of .NET Core application. Using such a workflow library can be useful to implement business rules visually or programmatically. ![elsa-overview](./elsa-overview.gif) @@ -8,15 +8,15 @@ This article shows how we can use this workflow library within our ABP-based app ## Source Code -You can find source code of the sample used in this article [here](https://github.com/abpframework/abp-samples/tree/elsa-demo). +You can find the source of the example solution used in this article [here](https://github.com/abpframework/abp-samples/tree/elsa-demo). ## Create the Project -In this article, I will create a new startup template with EF Core as a database provider and MVC/Razor-Pages for UI framework. +In this article, I will create a new startup template with EF Core as a database provider and MVC/Razor-Pages for the UI framework. -> If you already have a project with MVC/Razor-Pages or Blazor UI, you don't need to create a new startup template, you can directly implement the following steps to your existing project. In other words you can skip this section. +> If you already have a project with MVC/Razor-Pages or Blazor UI, you don't need to create a new startup template, you can directly implement the following steps to your existing project (you can skip this section). -* Before starting to the development, we will create a new solution named `ElsaDemo` (or whatever you want). We will create a new startup template with EF Core as a database provider and MVC/Razor-Pages for UI framework by using the [ABP CLI](https://docs.abp.io/en/abp/latest/CLI): +* We will create a new solution named `ElsaDemo` (or whatever you want). We will create a new startup template with **EF Core** as a database provider and **MVC/Razor-Pages** for the UI framework by using the [ABP CLI](https://docs.abp.io/en/abp/latest/CLI): ```bash abp new ElsaDemo @@ -32,17 +32,17 @@ dotnet ef migrations add Initial * After the initial migration created, we can run the `ElsaDemo.DbMigrator` project to apply migration into our database and seed initial data. -* After database and initial data created, we can run the `ElsaDemo.Web` to see our UI working properly. +* After the database and initial data created, we can run the `ElsaDemo.Web` to see our UI working properly. > Default admin username is **admin** and password is **1q2w3E*** -## Creating A Workflow (Hello World to Workflows) - Console Activity +## Creating First Workflow - Console Activity -We can start with creating our first workflow. Let's start with creating basic hello-world workflow. +We can start with creating our first workflow. Let's get started with creating a basic hello-world workflow by using console activity. In this example, we will **programmatically** define a workflow definition that displays the text **"Hello World from Elsa!"** to the console using Elsa's Workflow Builder API and run this workflow when the application initialized. ### Install Packages -We need to install two packages: `Elsa` and `Elsa.Activities.Console` into our `ElsaDemo.Web` project. You can add these two packages with the following command: +We need to add two packages: `Elsa` and `Elsa.Activities.Console` into our `ElsaDemo.Web` project. We can add these two packages with the following command: ```bash dotnet add package Elsa @@ -64,13 +64,13 @@ namespace ElsaDemo.Web.Workflows } ``` -* In here we've basically implemented the `IWorkflow` interface which only has one method named **Build**. In this method, we can define our workflow's executing steps (activities). +* In here we've basically implemented the `IWorkflow` interface which only has one method named **Build**. In this method, we can define our workflow's execution steps (activities). -* As you can see in the example above, we've used a activity named **WriteLine**, which writes a line of text to the console. We could also chain the activities one to another. +* As you can see in the example above, we've used an activity named **WriteLine**, which writes a line of text to the console. Elsa Core has many pre-defined activities like that. E.g **HttpEndpoint ** and **WriteHttpResponse** (we will see them both in the next chapter). -> "An activity is an atomic building block that represents a single executable step on the workflow." - [Elsa Core Definition](https://elsa-workflows.github.io/elsa-core/docs/next/concepts/concepts-workflows#activity) +> "An activity is an atomic building block that represents a single executable step on the workflow." - [Elsa Core Activity Definition](https://elsa-workflows.github.io/elsa-core/docs/next/concepts/concepts-workflows#activity) -* After defining our workflow, we need to register it. To do that, open your `ElsaDemoWebModule` class and update your `ElsaDemoWebModule` with the following lines. Most of the codes are abbreviated for simplicity. +* After defining our workflow, we need to define service registrations which required for the Elsa Core library to work properly. To do that, open your `ElsaDemoWebModule` class and update your `ElsaDemoWebModule` with the following lines. Most of the codes are abbreviated for simplicity. ```csharp using ElsaDemo.Web.Workflows; @@ -83,7 +83,7 @@ public override void ConfigureServices(ServiceConfigurationContext context) //... - ConfigureElsa(context); //add this line for Elsa's service registrations + ConfigureElsa(context); } private void ConfigureElsa(ServiceConfigurationContext context) @@ -105,25 +105,25 @@ public override void OnApplicationInitialization(ApplicationInitializationContex } ``` -* Here we basically, configured Elsa's services in our `ConfigureServices` method and after that in our `OnApplicationInitialization` method we get workflow runner (**IBuildsAndStartsWorkflow**) and started the our `HelloWorldConsole` workflow. +* Here we basically, configured Elsa's services in our `ConfigureServices` method and after that in our `OnApplicationInitialization` method we started the `HelloWorldConsole` workflow. * If we run the application and examine the console outputs, we should see the message that we defined in our workflow. ![hello-world-workflow](./hello-world-workflow.jpg) -## Creating A Workflow - Http Activity +## Creating A Workflow By Using Http Activities -In this example we will create a **Http Activity**. It will basically listen the specified route for incoming HTTP Request and write back a simple response. +In this example, we will create a workflow that uses **Http Activities**. It will basically listen the specified route for incoming HTTP Request and write back a simple response. -### Install Elsa.Activities.Http Package +### Add Elsa.Activities.Http Package -* Be able to use HTTP Activities we need to add `Elsa` (we've already installed it in previous section) and `Elsa.Activities.Http` packages into our web application. +* To be able to use **HTTP Activities** we need to add `Elsa` (we've already added in the previous chapter) and `Elsa.Activities.Http` packages into our web application. ```bash dotnet add package Elsa.Activities.Http ``` -* After the package installed we can create our workflow. So, create a class named `HelloWorldHttp` under **Workflows** folder. +* After the package installed, we can create our workflow. Let's started with creating a class named `HelloWorldHttp` under **Workflows** folder. ```csharp using System.Net; @@ -144,9 +144,9 @@ namespace ElsaDemo.Web.Workflows } ``` -* The above workflow has two activities. The first activity `HttpEndpoint` represents an HTTP endpoint, which can be invoked using an HTTP client, including a web browser. The first activity is connected to the second activity `WriteHttpResponse`, which writes a response to the HTTP client. +* The above workflow has two activities. The first activity `HttpEndpoint` represents an HTTP endpoint, which can be invoked using an HTTP client, including a web browser. The first activity is connected to the second activity `WriteHttpResponse`, which returns a simple response to us. -* After defined the **HelloWorldHttp** workflow we need to register it. So, open your `ElsaDemoWebModule` and update the `ConfigureElsa` method as below. +* After defined the **HelloWorldHttp** workflow we need to define this class as workflow. So, open your `ElsaDemoWebModule` and update the `ConfigureElsa` method as below. ```csharp private void ConfigureElsa(ServiceConfigurationContext context) @@ -155,13 +155,13 @@ private void ConfigureElsa(ServiceConfigurationContext context) { options .AddConsoleActivities() - .AddHttpActivities() //add this line to be able to use http activities + .AddHttpActivities() //add this line to be able to use the http activities .AddWorkflow() - .AddWorkflow(); //add new workflow that we defined + .AddWorkflow(); //workflow that we defined }); } ``` -* And add **HttpActivity** middleware to `OnApplicationInitilization` method of your `ElsaDemoWebModule` class. +* And add the **UseHttpActivities** middleware to `OnApplicationInitilization` method of your `ElsaDemoWebModule` class. ```csharp public override void OnApplicationInitialization(ApplicationInitializationContext context) @@ -171,19 +171,19 @@ public override void OnApplicationInitialization(ApplicationInitializationContex } ``` -* If we run the application and navigate to the "/hello-world" route we should see the response message that we've defined in our `HelloWorldHttp` workflow. +* If we run the application and navigate to the "/hello-world" route we should see the response message that we've defined (by using **WriteHttpResponse** activity) in our `HelloWorldHttp` workflow. ![hello-world-http](./hello-world-http.jpg) -## Integrate Elsa Dashboard To Our Application +## Integrate Elsa Dashboard To Application -* Until now we've created two workflows programmatically. But also we can create workflow visually by using Elsa's **HTML5 Workflow Designer**. +* Until now we've created two workflows programmatically. But also we can create workflows visually by using Elsa's **HTML5 Workflow Designer**. -* Being able to design our workflows basically and taking advantage of **HTML5 Workflow Designer** we will integrate the Elsa Dashboard to our application. So let's get started. +* Being able to design our workflows easily and taking advantage of **HTML5 Workflow Designer** we will integrate the Elsa Dashboard to our application. ### Install Packages -* Following three package installation required for Elsa Server. +* Following three packages required for Elsa Server. ```bash dotnet add package Elsa.Activities.Temporal.Quartz @@ -191,15 +191,15 @@ dotnet add package Elsa.Persistence.EntityFramework.SqlServer dotnet add package Elsa.Server.Api ``` -> Also we need to install the **Elsa** and **Elsa.Activities.Http** packages but we've already installed these packages in the previous chapters. +> Also, we need to install the **Elsa** and **Elsa.Activities.Http** packages but we've already installed these packages in the previous chapters. -* We need to install one more package named `Elsa.Designer.Components.Web`. This package provides us components for our dashboard. +* We need to install one more package named `Elsa.Designer.Components.Web`. This package provides us the **Elsa Dashboard** component. ```bash dotnet add package Elsa.Designer.Components.Web ``` -* After the package installations completed, we need to make the neccessarily configurations to be able to use the **Elsa Server** and **Elsa Dashboard**. Therefore, open your `ElsaDemoWebModule` class and make the neccessarily changes as below. +* After the package installations completed, we need to make the necessary configurations to be able to use the **Elsa Server** and **Elsa Dashboard**. Therefore, open your `ElsaDemoWebModule` class and make the necessary changes as below. ```csharp public override void ConfigureServices(ServiceConfigurationContext context) @@ -223,7 +223,6 @@ private void ConfigureElsa(ServiceConfigurationContext context, IConfiguration c configuration.GetConnectionString("Default"))) .AddConsoleActivities() .AddHttpActivities(elsaSection.GetSection("Server").Bind) - // .AddEmailActivities(elsaSection.GetSection("Smtp").Bind) .AddQuartzTemporalActivities() .AddJavaScriptActivities() .AddWorkflowsFrom(); @@ -246,7 +245,7 @@ private void ConfigureElsa(ServiceConfigurationContext context, IConfiguration c Configure(options => { options.AutoValidateFilter = type => - type.Assembly != typeof(Elsa.Server.Api.Endpoints.WorkflowRegistry.Get).Assembly; + type.Assembly != typeof(Elsa.Server.Api.Endpoints.WorkflowRegistry.Get).Assembly; }); } @@ -267,25 +266,14 @@ public override void OnApplicationInitialization(ApplicationInitializationContex } ``` -* We don't need to register our workflows one by one anymore. Because now we use `.AddWorkflowsFrom()`, and this register workflows behalf of us. +* We don't need to register our workflows one by one anymore. Because now we use `.AddWorkflowsFrom()`, and this registers workflows on our behalf. -* As you can notice here, we use a section named `Elsa` and its sub-sections from configuration sytem but we didn't define them yet. Let's define them. So open your `appsettings.json` and update its content as below. +* As you may notice here, we use a section named `Elsa` and its sub-sections from the configuration system but we didn't define them yet. To define them open your `appsettings.json` and add the following Elsa section into this file. ```json { - "App": { - "SelfUrl": "https://localhost:44336" - }, - "ConnectionStrings": { - "Default": "Server=localhost;Database=ElsaDemo;Trusted_Connection=True" - }, - "AuthServer": { - "Authority": "https://localhost:44336", - "RequireHttpsMetadata": "false" - }, - "StringEncryption": { - "DefaultPassPhrase": "***********" - }, + //... + "Elsa": { "Http": { "BaseUrl": "https://localhost:44336" @@ -296,9 +284,9 @@ public override void OnApplicationInitialization(ApplicationInitializationContex #### Define Permission For Elsa Dashboard -* After those configurations, we can define a [permission](https://docs.abp.io/en/abp/latest/Authorization#permission-system) to be assure of only allowed users can see the Elsa Dashboard. +* We can define a [permission](https://docs.abp.io/en/abp/latest/Authorization#permission-system) to be assured of only allowed users can see the Elsa Dashboard. -* Open your `ElsaDemoPermissions` class under the **Permissions** folder (in `ElsaDemo.Application.Contracts` layer) and add the following permission name. +* Open your `ElsaDemoPermissions` class under the **Permissions** folder (in the `ElsaDemo.Application.Contracts` layer) and add the following permission name. ```csharp namespace ElsaDemo.Permissions @@ -307,7 +295,7 @@ namespace ElsaDemo.Permissions { public const string GroupName = "ElsaDemo"; - public const string ElsaDashboard = GroupName + ".ElsaDashboard"; //add this line + public const string ElsaDashboard = GroupName + ".ElsaDashboard"; } } ``` @@ -338,7 +326,7 @@ namespace ElsaDemo.Permissions } ``` -* As you notice we've used a localized value (**Permission:ElsaDashboard**) but haven't add this localization key and value to the localization file, so let's add this localization key and value. To do this, open your `en.json` file under **Localization/ElsaDemo** folder (under **DomainShared** layer) and add this localization key. +* As you can notice, we've used a localized value (**L("Permission:ElsaDashboard")**) but haven't added this localization key and value to the localization file, so let's add this localization key and value. To do this, open your `en.json` file under **Localization/ElsaDemo** folder (under the **DomainShared** layer) and add this localization key. ```json { @@ -352,11 +340,9 @@ namespace ElsaDemo.Permissions } ``` -> You can also add this localization key to the other localization files such as **tr.json**. - -#### Add Elsa Dashboard To Application +#### Add Elsa Dashboard Component To Application -* After those configurations, now we can add Elsa Dashboard to our application with authorization check. To do this, create a razor page named **_Host.cshtml** under **Pages** folder and update its content as below. +* After those configurations, now we can add Elsa Dashboard to our application with an authorization check. To do this, create a razor page named **_Host.cshtml** (under **Pages** folder) and update its content as below. ```html @page "/elsa" @@ -386,11 +372,11 @@ namespace ElsaDemo.Permissions ``` -* As you may notice, we've defined an attribute for authorization check. This provides us only the user who has the **ElsaDemoPermissions.ElsaDashboard** permission allowed to see this page. +* We've defined an attribute for authorization check here. With this authorization check, only the user who has the **Elsa Dashboard** permission allowed to see this page. #### Add Elsa Dashboard Page To Main Menu -* We can open the `ElsaDemoMenuContributor` class under **Menus** folder and define the menu item for reaching the Elsa Dashboard easily. +* We can open the `ElsaDemoMenuContributor` class under the **Menus** folder and define the menu item for reaching the Elsa Dashboard easily. ```csharp using System.Threading.Tasks; @@ -430,6 +416,7 @@ namespace ElsaDemo.Web.Menus ) ); + //add Workflow menu-item context.Menu.Items.Insert( 1, new ApplicationMenuItem( @@ -448,18 +435,16 @@ namespace ElsaDemo.Web.Menus } ``` -* With that menu item configuration, only the user who has **ElsaDemoPermissions.ElsaDashboard** permission allowed to see the defined menu item. +* With that menu item configuration, only the user who has **Elsa Dashboard** permission allowed to see the defined menu item. ## Result -* Let's run the application and login. - -> Default admin username is **admin** and password is **1q2w3E*** +* Let's run the application and see how it looks like. ![workflow-main-menu-item](./workflow-main-menu.jpg) > If the account you are logged in has the **ElsaDemoPermissions.ElsaDashboard** permission, you should see the **Workflow** menu item. If you do not see this menu item, please be assured that your logged-in account has that permission. -* Now we can click the workflow menu item, display the Elsa Dashboard and designing workflows. +* Now we can click the "Workflow" menu item, display the Elsa Dashboard and designing workflows. ![elsa-demo-result](./elsa-demo-result.gif) \ No newline at end of file