From 81a6f3893e71c6dccd2b8e533f4f0310f495da95 Mon Sep 17 00:00:00 2001 From: Sipke Schoorstra Date: Sat, 5 Jan 2019 21:19:13 +0100 Subject: [PATCH] Added expression editor view component --- .../Activities/HttpRequestAction.cs | 31 +++++++++++++++++++ .../ActivityDescriptors.cs | 6 ++++ .../Drivers/HttpRequestTriggerAction.cs | 24 ++++++++++++++ .../Expressions/WorkflowExpression.cs | 19 +++++++----- .../Extensions/ServiceCollectionExtensions.cs | 6 ++-- .../Display/HttpRequestActionDisplay.cs | 25 +++++++++++++++ .../HttpRequestTriggerDisplay.cs | 2 +- .../Elsa.Web.Activities.Http.csproj | 3 +- .../Elsa.Web.Activities.Http/Startup.cs | 5 +-- .../ViewModels/HttpRequestActionViewModel.cs | 27 ++++++++++++++++ .../Views/HttpRequestAction.Card.cshtml | 6 ++++ .../Views/HttpRequestAction.Design.cshtml | 6 ++++ .../Views/HttpRequestAction.Edit.cshtml | 20 ++++++++++++ .../Views/HttpRequestTrigger.Edit.cshtml | 9 +++--- .../Views/_ViewImports.cshtml | 6 +++- .../Elsa.Web.Components.csproj | 20 ++++++------ .../ViewComponents/ExpressionEditor.cs | 25 +++++++++++++++ .../ViewModels/ExpressionViewModel.cs | 21 +++++++++++++ .../ExpressionEditor/Default.cshtml | 7 +++++ .../Views/_ViewImports.cshtml | 4 ++- 20 files changed, 240 insertions(+), 32 deletions(-) create mode 100644 src/activities/Elsa.Activities.Http/Activities/HttpRequestAction.cs create mode 100644 src/activities/Elsa.Activities.Http/Drivers/HttpRequestTriggerAction.cs create mode 100644 src/web/modules/Elsa.Web.Activities.Http/Display/HttpRequestActionDisplay.cs rename src/web/modules/Elsa.Web.Activities.Http/{Drivers => Display}/HttpRequestTriggerDisplay.cs (94%) create mode 100644 src/web/modules/Elsa.Web.Activities.Http/ViewModels/HttpRequestActionViewModel.cs create mode 100644 src/web/modules/Elsa.Web.Activities.Http/Views/HttpRequestAction.Card.cshtml create mode 100644 src/web/modules/Elsa.Web.Activities.Http/Views/HttpRequestAction.Design.cshtml create mode 100644 src/web/modules/Elsa.Web.Activities.Http/Views/HttpRequestAction.Edit.cshtml create mode 100644 src/web/modules/Elsa.Web.Components/ViewComponents/ExpressionEditor.cs create mode 100644 src/web/modules/Elsa.Web.Components/ViewModels/ExpressionViewModel.cs create mode 100644 src/web/modules/Elsa.Web.Components/Views/Shared/Components/ExpressionEditor/Default.cshtml diff --git a/src/activities/Elsa.Activities.Http/Activities/HttpRequestAction.cs b/src/activities/Elsa.Activities.Http/Activities/HttpRequestAction.cs new file mode 100644 index 000000000..b0faf6295 --- /dev/null +++ b/src/activities/Elsa.Activities.Http/Activities/HttpRequestAction.cs @@ -0,0 +1,31 @@ +using System; +using System.Collections.Generic; +using Elsa.Activities.Http.Models; +using Elsa.Expressions; +using Elsa.Models; + +namespace Elsa.Activities.Http.Activities +{ + public class HttpRequestAction : Activity + { + /// + /// The URL to invoke. + /// + public Uri Url { get; set; } + + /// + /// The HTTP method to use. + /// + public string Method { get; set; } + + /// + /// The body to send along with the request + /// + public WorkflowExpression Body { get; set; } + + /// + /// The body to send along with the request + /// + public IDictionary RequestHeaders { get; set; } + } +} \ No newline at end of file diff --git a/src/activities/Elsa.Activities.Http/ActivityDescriptors.cs b/src/activities/Elsa.Activities.Http/ActivityDescriptors.cs index 932fefea9..7799378e1 100644 --- a/src/activities/Elsa.Activities.Http/ActivityDescriptors.cs +++ b/src/activities/Elsa.Activities.Http/ActivityDescriptors.cs @@ -22,6 +22,12 @@ namespace Elsa.Activities.Http T["HTTP Request Trigger"], T["Triggers when an incoming HTTP request is received."], T["Done"]); + + yield return ActivityDescriptor.ForAction( + Category, + T["HTTP Request"], + T["Execute a HTTP request."], + T["Done"]); } } } \ No newline at end of file diff --git a/src/activities/Elsa.Activities.Http/Drivers/HttpRequestTriggerAction.cs b/src/activities/Elsa.Activities.Http/Drivers/HttpRequestTriggerAction.cs new file mode 100644 index 000000000..69229186e --- /dev/null +++ b/src/activities/Elsa.Activities.Http/Drivers/HttpRequestTriggerAction.cs @@ -0,0 +1,24 @@ +using System.Threading; +using System.Threading.Tasks; +using Elsa.Activities.Http.Activities; +using Elsa.Handlers; +using Elsa.Models; +using Elsa.Results; + +namespace Elsa.Activities.Http.Drivers +{ + public class HttpRequestActionDriver : ActivityDriver + { + private readonly IWorkflowExpressionEvaluator expressionEvaluator; + + public HttpRequestActionDriver(IWorkflowExpressionEvaluator expressionEvaluator) + { + this.expressionEvaluator = expressionEvaluator; + } + + protected override async Task OnExecuteAsync(HttpRequestAction activity, WorkflowExecutionContext workflowContext, CancellationToken cancellationToken) + { + return TriggerEndpoint("Done"); + } + } +} \ No newline at end of file diff --git a/src/core/Elsa.Abstractions/Expressions/WorkflowExpression.cs b/src/core/Elsa.Abstractions/Expressions/WorkflowExpression.cs index 5d0deeba7..ad7a2b842 100644 --- a/src/core/Elsa.Abstractions/Expressions/WorkflowExpression.cs +++ b/src/core/Elsa.Abstractions/Expressions/WorkflowExpression.cs @@ -1,20 +1,23 @@ namespace Elsa.Expressions { - public class WorkflowExpression + public class WorkflowExpression { - public WorkflowExpression() - { - } - - public WorkflowExpression(string syntax, string expression) + protected WorkflowExpression(string syntax, string expression) { Syntax = syntax; Expression = expression; } - public string Syntax { get; set; } - public string Expression { get; set; } + public string Syntax { get; } + public string Expression { get; } public override string ToString() => Expression; } + + public class WorkflowExpression : WorkflowExpression + { + public WorkflowExpression(string syntax, string expression) : base(syntax, expression) + { + } + } } \ No newline at end of file diff --git a/src/core/Elsa.Core/Extensions/ServiceCollectionExtensions.cs b/src/core/Elsa.Core/Extensions/ServiceCollectionExtensions.cs index 4a9cd4f22..e04fa3447 100644 --- a/src/core/Elsa.Core/Extensions/ServiceCollectionExtensions.cs +++ b/src/core/Elsa.Core/Extensions/ServiceCollectionExtensions.cs @@ -25,7 +25,9 @@ namespace Elsa.Extensions services.TryAddSingleton(); services.AddSingleton(); services.AddSingleton(); - + services.AddSingleton(); + services.AddSingleton(); + return services; } @@ -34,8 +36,6 @@ namespace Elsa.Extensions services.TryAddSingleton(); services.TryAddSingleton(); services.TryAddSingleton(); - services.AddSingleton(); - services.AddSingleton(); services.TryAddSingleton(); return services; diff --git a/src/web/modules/Elsa.Web.Activities.Http/Display/HttpRequestActionDisplay.cs b/src/web/modules/Elsa.Web.Activities.Http/Display/HttpRequestActionDisplay.cs new file mode 100644 index 000000000..9b9cc6bff --- /dev/null +++ b/src/web/modules/Elsa.Web.Activities.Http/Display/HttpRequestActionDisplay.cs @@ -0,0 +1,25 @@ +using Elsa.Activities.Http.Activities; +using Elsa.Expressions; +using Elsa.Web.Activities.Http.ViewModels; +using Elsa.Web.Components.ViewModels; +using Elsa.Web.Drivers; + +namespace Elsa.Web.Activities.Http.Display +{ + public class HttpRequestActionDisplay : ActivityDisplayDriver + { + protected override void EditActivity(HttpRequestAction activity, HttpRequestActionViewModel model) + { + model.Method = activity.Method; + model.Body = new ExpressionViewModel(activity.Body); + model.Url = activity.Url; + } + + protected override void UpdateActivity(HttpRequestActionViewModel model, HttpRequestAction activity) + { + activity.Method = model.Method; + activity.Body = model.Body.ToWorkflowExpression(); + activity.Url = model.Url; + } + } +} \ No newline at end of file diff --git a/src/web/modules/Elsa.Web.Activities.Http/Drivers/HttpRequestTriggerDisplay.cs b/src/web/modules/Elsa.Web.Activities.Http/Display/HttpRequestTriggerDisplay.cs similarity index 94% rename from src/web/modules/Elsa.Web.Activities.Http/Drivers/HttpRequestTriggerDisplay.cs rename to src/web/modules/Elsa.Web.Activities.Http/Display/HttpRequestTriggerDisplay.cs index 40124d9f6..08c7e5903 100644 --- a/src/web/modules/Elsa.Web.Activities.Http/Drivers/HttpRequestTriggerDisplay.cs +++ b/src/web/modules/Elsa.Web.Activities.Http/Display/HttpRequestTriggerDisplay.cs @@ -2,7 +2,7 @@ using Elsa.Web.Activities.Http.ViewModels; using Elsa.Web.Drivers; -namespace Elsa.Web.Activities.Http.Drivers +namespace Elsa.Web.Activities.Http.Display { public class HttpRequestTriggerDisplay : ActivityDisplayDriver { diff --git a/src/web/modules/Elsa.Web.Activities.Http/Elsa.Web.Activities.Http.csproj b/src/web/modules/Elsa.Web.Activities.Http/Elsa.Web.Activities.Http.csproj index 776b5d705..b25ab3cac 100644 --- a/src/web/modules/Elsa.Web.Activities.Http/Elsa.Web.Activities.Http.csproj +++ b/src/web/modules/Elsa.Web.Activities.Http/Elsa.Web.Activities.Http.csproj @@ -1,4 +1,4 @@ - + netstandard2.0 @@ -15,6 +15,7 @@ + diff --git a/src/web/modules/Elsa.Web.Activities.Http/Startup.cs b/src/web/modules/Elsa.Web.Activities.Http/Startup.cs index 2d64752d3..e7966d38f 100644 --- a/src/web/modules/Elsa.Web.Activities.Http/Startup.cs +++ b/src/web/modules/Elsa.Web.Activities.Http/Startup.cs @@ -1,5 +1,5 @@ using Elsa.Activities.Http.Extensions; -using Elsa.Web.Activities.Http.Drivers; +using Elsa.Web.Activities.Http.Display; using Elsa.Web.Extensions; using Microsoft.Extensions.DependencyInjection; using OrchardCore.Modules; @@ -12,7 +12,8 @@ namespace Elsa.Web.Activities.Http { services .AddHttpWorkflowDescriptors() - .AddActivityDisplay(); + .AddActivityDisplay() + .AddActivityDisplay(); } } } \ No newline at end of file diff --git a/src/web/modules/Elsa.Web.Activities.Http/ViewModels/HttpRequestActionViewModel.cs b/src/web/modules/Elsa.Web.Activities.Http/ViewModels/HttpRequestActionViewModel.cs new file mode 100644 index 000000000..8845751f9 --- /dev/null +++ b/src/web/modules/Elsa.Web.Activities.Http/ViewModels/HttpRequestActionViewModel.cs @@ -0,0 +1,27 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.Linq; +using Elsa.Expressions; +using Elsa.Web.Components.ViewModels; +using Microsoft.AspNetCore.Mvc.Rendering; + +namespace Elsa.Web.Activities.Http.ViewModels +{ + public class HttpRequestActionViewModel + { + [Required] + public Uri Url { get; set; } + + [Required] + public string Method { get; set; } + + public ExpressionViewModel Body { get; set; } + + public ICollection GetAvailableHttpMethods() + { + var availableHttpMethods = new[] { "GET", "POST", "PUT", "DELETE", "OPTIONS" }; + return availableHttpMethods.Select(x => new SelectListItem { Text = x, Value = x }).ToList(); + } + } +} \ No newline at end of file diff --git a/src/web/modules/Elsa.Web.Activities.Http/Views/HttpRequestAction.Card.cshtml b/src/web/modules/Elsa.Web.Activities.Http/Views/HttpRequestAction.Card.cshtml new file mode 100644 index 000000000..0f133d8f1 --- /dev/null +++ b/src/web/modules/Elsa.Web.Activities.Http/Views/HttpRequestAction.Card.cshtml @@ -0,0 +1,6 @@ +@model ActivityShapeModel +@{ + var activityDescriptor = Model.Activity.Descriptor; +} +

@activityDescriptor.DisplayText

+

@activityDescriptor.Description

\ No newline at end of file diff --git a/src/web/modules/Elsa.Web.Activities.Http/Views/HttpRequestAction.Design.cshtml b/src/web/modules/Elsa.Web.Activities.Http/Views/HttpRequestAction.Design.cshtml new file mode 100644 index 000000000..11e91076f --- /dev/null +++ b/src/web/modules/Elsa.Web.Activities.Http/Views/HttpRequestAction.Design.cshtml @@ -0,0 +1,6 @@ +@model ActivityShapeModel + +
+

@Model.DisplayText

+ "@($"{Model.Activity.Method} {Model.Activity.Url}")" +
\ No newline at end of file diff --git a/src/web/modules/Elsa.Web.Activities.Http/Views/HttpRequestAction.Edit.cshtml b/src/web/modules/Elsa.Web.Activities.Http/Views/HttpRequestAction.Edit.cshtml new file mode 100644 index 000000000..52a2736d0 --- /dev/null +++ b/src/web/modules/Elsa.Web.Activities.Http/Views/HttpRequestAction.Edit.cshtml @@ -0,0 +1,20 @@ +@using OrchardCore.Mvc.Core.Utilities +@model HttpRequestActionViewModel +
+ + + + @T["The relative path that will trigger this activity. Example: '/webhooks/my'"] +
+
+ + + + @T["The HTTP method to use for the request."] +
+
+ + + + @T["The HTTP request body to send along with the request."] +
\ No newline at end of file diff --git a/src/web/modules/Elsa.Web.Activities.Http/Views/HttpRequestTrigger.Edit.cshtml b/src/web/modules/Elsa.Web.Activities.Http/Views/HttpRequestTrigger.Edit.cshtml index 37456fcf7..b8ca1a077 100644 --- a/src/web/modules/Elsa.Web.Activities.Http/Views/HttpRequestTrigger.Edit.cshtml +++ b/src/web/modules/Elsa.Web.Activities.Http/Views/HttpRequestTrigger.Edit.cshtml @@ -1,5 +1,4 @@ -@using OrchardCore.Mvc.Core.Utilities -@model Elsa.Web.Activities.Http.ViewModels.HttpRequestTriggerViewModel +@model HttpRequestTriggerViewModel
@@ -15,19 +14,19 @@ - @T["The HTTP method to match.'"] + @T["The HTTP method to match."]
- @T["Check to generate a nonce that needs to be included when invoking the URL.'"] + @T["Check to generate a nonce that needs to be included when invoking the URL."]
- @T["Check to read the request body. If the content type represents a form, the body is parsed as a collection of key/value pairs. Otherwise the body is stored as a raw string'"] + @T["Check to read the request body. If the content type represents a form, the body is parsed as a collection of key/value pairs. Otherwise the body is stored as a raw string"]
\ No newline at end of file diff --git a/src/web/modules/Elsa.Web.Activities.Http/Views/_ViewImports.cshtml b/src/web/modules/Elsa.Web.Activities.Http/Views/_ViewImports.cshtml index ecd78fc31..0aff3f346 100644 --- a/src/web/modules/Elsa.Web.Activities.Http/Views/_ViewImports.cshtml +++ b/src/web/modules/Elsa.Web.Activities.Http/Views/_ViewImports.cshtml @@ -1,3 +1,7 @@ +@using Elsa.Web.Activities.Http.ViewModels +@using Elsa.Web.ViewModels @using Elsa.Activities.Http.Activities +@using OrchardCore.Mvc.Core.Utilities @inherits OrchardCore.DisplayManagement.Razor.RazorPage -@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers \ No newline at end of file +@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers +@addTagHelper *, Elsa.Web.Components \ No newline at end of file diff --git a/src/web/modules/Elsa.Web.Components/Elsa.Web.Components.csproj b/src/web/modules/Elsa.Web.Components/Elsa.Web.Components.csproj index dbdec49f2..bb2a788d7 100644 --- a/src/web/modules/Elsa.Web.Components/Elsa.Web.Components.csproj +++ b/src/web/modules/Elsa.Web.Components/Elsa.Web.Components.csproj @@ -1,7 +1,7 @@  - netcoreapp2.1 + netstandard2.0 Elsa.Web.Components 1.0.0 Sipke Schoorstra @@ -14,24 +14,24 @@ - - - + + + - - - - + + + + - + - + \ No newline at end of file diff --git a/src/web/modules/Elsa.Web.Components/ViewComponents/ExpressionEditor.cs b/src/web/modules/Elsa.Web.Components/ViewComponents/ExpressionEditor.cs new file mode 100644 index 000000000..7ef77d9e6 --- /dev/null +++ b/src/web/modules/Elsa.Web.Components/ViewComponents/ExpressionEditor.cs @@ -0,0 +1,25 @@ +using System.Collections.Generic; +using System.Linq; +using Elsa.Web.Components.ViewModels; +using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Mvc.Rendering; + +namespace Elsa.Web.Components.ViewComponents +{ + public class ExpressionEditor : ViewComponent + { + private readonly IEnumerable evaluators; + + public ExpressionEditor(IEnumerable evaluators) + { + this.evaluators = evaluators; + } + + public IViewComponentResult Invoke(ExpressionViewModel model, string prefix) + { + ViewContext.ViewData.TemplateInfo.HtmlFieldPrefix = prefix; + ViewContext.ViewBag.Syntaxes = evaluators.Select(x => new SelectListItem(x.Syntax, x.Syntax)); + return View(model); + } + } +} \ No newline at end of file diff --git a/src/web/modules/Elsa.Web.Components/ViewModels/ExpressionViewModel.cs b/src/web/modules/Elsa.Web.Components/ViewModels/ExpressionViewModel.cs new file mode 100644 index 000000000..25cb75366 --- /dev/null +++ b/src/web/modules/Elsa.Web.Components/ViewModels/ExpressionViewModel.cs @@ -0,0 +1,21 @@ +using Elsa.Expressions; + +namespace Elsa.Web.Components.ViewModels +{ + public class ExpressionViewModel + { + public ExpressionViewModel() + { + } + + public ExpressionViewModel(WorkflowExpression workflowExpression) + { + Expression = workflowExpression?.Expression; + Syntax = workflowExpression?.Syntax; + } + + public string Expression { get; set; } + public string Syntax { get; set; } + public WorkflowExpression ToWorkflowExpression() => new WorkflowExpression(Syntax, Expression); + } +} \ No newline at end of file diff --git a/src/web/modules/Elsa.Web.Components/Views/Shared/Components/ExpressionEditor/Default.cshtml b/src/web/modules/Elsa.Web.Components/Views/Shared/Components/ExpressionEditor/Default.cshtml new file mode 100644 index 000000000..8f4c60208 --- /dev/null +++ b/src/web/modules/Elsa.Web.Components/Views/Shared/Components/ExpressionEditor/Default.cshtml @@ -0,0 +1,7 @@ +@model ExpressionViewModel +
+ +
+ +
+
\ No newline at end of file diff --git a/src/web/modules/Elsa.Web.Components/Views/_ViewImports.cshtml b/src/web/modules/Elsa.Web.Components/Views/_ViewImports.cshtml index 31ea702ff..2eee85f41 100644 --- a/src/web/modules/Elsa.Web.Components/Views/_ViewImports.cshtml +++ b/src/web/modules/Elsa.Web.Components/Views/_ViewImports.cshtml @@ -1,5 +1,7 @@ +@using Elsa.Web.Components.ViewModels @inherits OrchardCore.DisplayManagement.Razor.RazorPage @namespace Elsa.Web.Components.Views @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers @addTagHelper *, OrchardCore.DisplayManagement -@addTagHelper *, OrchardCore.ResourceManagement \ No newline at end of file +@addTagHelper *, OrchardCore.ResourceManagement +@addTagHelper *, Elsa.Web.Components \ No newline at end of file