From 04bacaa2819c1421119fce69121aaa65b25c6df2 Mon Sep 17 00:00:00 2001 From: axeleron007 Date: Tue, 21 Sep 2021 14:04:37 +0300 Subject: [PATCH] fixes --- .../Activities/HttpEndpoint/HttpEndpoint.cs | 6 ++ .../Design/ActivityInputUIHints.cs | 1 + .../elsa-workflows-studio/src/components.d.ts | 17 +++++ .../tree/elsa-designer-tree/models.ts | 3 +- .../elsa-url-property/elsa-url-property.tsx | 49 +++++++++++++ ...elsa-workflow-definition-editor-screen.tsx | 3 +- .../elsa-workflow-test-panel.tsx | 68 ++++++++++--------- .../src/drivers/index.ts | 1 + .../src/drivers/url-driver.tsx | 12 ++++ .../src/models/domain.ts | 1 + .../src/plugins/default-drivers-plugin.ts | 5 +- .../ActivityExecutionResultExecutedHandler.cs | 17 ++++- .../Models/WorkflowTestMessage.cs | 1 + 13 files changed, 145 insertions(+), 39 deletions(-) create mode 100644 src/designer/elsa-workflows-studio/src/components/editors/properties/elsa-url-property/elsa-url-property.tsx create mode 100644 src/designer/elsa-workflows-studio/src/drivers/url-driver.tsx diff --git a/src/activities/Elsa.Activities.Http/Activities/HttpEndpoint/HttpEndpoint.cs b/src/activities/Elsa.Activities.Http/Activities/HttpEndpoint/HttpEndpoint.cs index cb5372e1b..9c573e33b 100644 --- a/src/activities/Elsa.Activities.Http/Activities/HttpEndpoint/HttpEndpoint.cs +++ b/src/activities/Elsa.Activities.Http/Activities/HttpEndpoint/HttpEndpoint.cs @@ -64,6 +64,12 @@ namespace Elsa.Activities.Http OptionsProvider = typeof(HttpEndpoint))] public string? Schema { get; set; } + [ActivityInput( + Category = PropertyCategories.Advanced, + DefaultValue = "https://extendsclass.com/json-schema-validator.html", + UIHint = ActivityInputUIHints.Url)] + public string? OnlineConverter { get; set; } + [ActivityInput( Hint = "Check to allow authenticated requests only", SupportedSyntaxes = new[] { SyntaxNames.Literal, SyntaxNames.JavaScript, SyntaxNames.Liquid }, diff --git a/src/core/Elsa.Abstractions/Design/ActivityInputUIHints.cs b/src/core/Elsa.Abstractions/Design/ActivityInputUIHints.cs index e554cba9f..7c5871cfa 100644 --- a/src/core/Elsa.Abstractions/Design/ActivityInputUIHints.cs +++ b/src/core/Elsa.Abstractions/Design/ActivityInputUIHints.cs @@ -10,6 +10,7 @@ namespace Elsa.Design public const string Dropdown = "dropdown"; public const string MultiText = "multi-text"; public const string CodeEditor = "code-editor"; + public const string Url = "url"; /// /// An editor that allows the user to write a blob of JSON. diff --git a/src/designer/elsa-workflows-studio/src/components.d.ts b/src/designer/elsa-workflows-studio/src/components.d.ts index 0477b3163..64531b0ef 100644 --- a/src/designer/elsa-workflows-studio/src/components.d.ts +++ b/src/designer/elsa-workflows-studio/src/components.d.ts @@ -228,6 +228,10 @@ export namespace Components { "hide": () => Promise; "show": (options: ToastNotificationOptions) => Promise; } + interface ElsaUrlProperty { + "propertyDescriptor": ActivityPropertyDescriptor; + "propertyModel": ActivityDefinitionProperty; + } interface ElsaWebhookDefinitionEditorNotifications { } interface ElsaWebhookDefinitionEditorScreen { @@ -575,6 +579,12 @@ declare global { prototype: HTMLElsaToastNotificationElement; new (): HTMLElsaToastNotificationElement; }; + interface HTMLElsaUrlPropertyElement extends Components.ElsaUrlProperty, HTMLStencilElement { + } + var HTMLElsaUrlPropertyElement: { + prototype: HTMLElsaUrlPropertyElement; + new (): HTMLElsaUrlPropertyElement; + }; interface HTMLElsaWebhookDefinitionEditorNotificationsElement extends Components.ElsaWebhookDefinitionEditorNotifications, HTMLStencilElement { } var HTMLElsaWebhookDefinitionEditorNotificationsElement: { @@ -718,6 +728,7 @@ declare global { "elsa-tab-content": HTMLElsaTabContentElement; "elsa-tab-header": HTMLElsaTabHeaderElement; "elsa-toast-notification": HTMLElsaToastNotificationElement; + "elsa-url-property": HTMLElsaUrlPropertyElement; "elsa-webhook-definition-editor-notifications": HTMLElsaWebhookDefinitionEditorNotificationsElement; "elsa-webhook-definition-editor-screen": HTMLElsaWebhookDefinitionEditorScreenElement; "elsa-webhook-definitions-list-screen": HTMLElsaWebhookDefinitionsListScreenElement; @@ -950,6 +961,10 @@ declare namespace LocalJSX { } interface ElsaToastNotification { } + interface ElsaUrlProperty { + "propertyDescriptor"?: ActivityPropertyDescriptor; + "propertyModel"?: ActivityDefinitionProperty; + } interface ElsaWebhookDefinitionEditorNotifications { } interface ElsaWebhookDefinitionEditorScreen { @@ -1091,6 +1106,7 @@ declare namespace LocalJSX { "elsa-tab-content": ElsaTabContent; "elsa-tab-header": ElsaTabHeader; "elsa-toast-notification": ElsaToastNotification; + "elsa-url-property": ElsaUrlProperty; "elsa-webhook-definition-editor-notifications": ElsaWebhookDefinitionEditorNotifications; "elsa-webhook-definition-editor-screen": ElsaWebhookDefinitionEditorScreen; "elsa-webhook-definitions-list-screen": ElsaWebhookDefinitionsListScreen; @@ -1154,6 +1170,7 @@ declare module "@stencil/core" { "elsa-tab-content": LocalJSX.ElsaTabContent & JSXBase.HTMLAttributes; "elsa-tab-header": LocalJSX.ElsaTabHeader & JSXBase.HTMLAttributes; "elsa-toast-notification": LocalJSX.ElsaToastNotification & JSXBase.HTMLAttributes; + "elsa-url-property": LocalJSX.ElsaUrlProperty & JSXBase.HTMLAttributes; "elsa-webhook-definition-editor-notifications": LocalJSX.ElsaWebhookDefinitionEditorNotifications & JSXBase.HTMLAttributes; "elsa-webhook-definition-editor-screen": LocalJSX.ElsaWebhookDefinitionEditorScreen & JSXBase.HTMLAttributes; "elsa-webhook-definitions-list-screen": LocalJSX.ElsaWebhookDefinitionsListScreen & JSXBase.HTMLAttributes; diff --git a/src/designer/elsa-workflows-studio/src/components/designers/tree/elsa-designer-tree/models.ts b/src/designer/elsa-workflows-studio/src/components/designers/tree/elsa-designer-tree/models.ts index e3706e4eb..0b5dd3c59 100644 --- a/src/designer/elsa-workflows-studio/src/components/designers/tree/elsa-designer-tree/models.ts +++ b/src/designer/elsa-workflows-studio/src/components/designers/tree/elsa-designer-tree/models.ts @@ -3,7 +3,8 @@ export enum WorkflowDesignerMode { Edit, Instance, - Blueprint + Blueprint, + Test } export interface ActivityContextMenuState { diff --git a/src/designer/elsa-workflows-studio/src/components/editors/properties/elsa-url-property/elsa-url-property.tsx b/src/designer/elsa-workflows-studio/src/components/editors/properties/elsa-url-property/elsa-url-property.tsx new file mode 100644 index 000000000..3556e9874 --- /dev/null +++ b/src/designer/elsa-workflows-studio/src/components/editors/properties/elsa-url-property/elsa-url-property.tsx @@ -0,0 +1,49 @@ +import {Component, h, Prop, State} from '@stencil/core'; +import {ActivityDefinitionProperty, ActivityPropertyDescriptor, SyntaxNames} from "../../../../models"; + +@Component({ + tag: 'elsa-url-property', + shadow: false, +}) +export class ElsaUrlProperty { + + @Prop() propertyDescriptor: ActivityPropertyDescriptor; + @Prop() propertyModel: ActivityDefinitionProperty; + @State() currentValue: string; + + componentWillLoad() { + const defaultSyntax = this.propertyDescriptor.defaultSyntax || SyntaxNames.Literal; + this.currentValue = this.propertyModel.expressions[defaultSyntax] || undefined; + } + + onUrlClick(e: MouseEvent, url: string) { + e.preventDefault(); + window.open(url, '_blank', 'noopener,noreferrer'); + } + + render() { + const propertyDescriptor = this.propertyDescriptor; + const propertyModel = this.propertyModel; + const propertyName = propertyDescriptor.name; + const fieldLabel = propertyDescriptor.label || propertyName; + let value = this.currentValue; + + if (value == undefined) { + const defaultValue = this.propertyDescriptor.defaultValue; + value = defaultValue ? defaultValue.toString() : undefined; + } + + return ( + + this.onUrlClick(e, value)} + class="elsa-relative elsa-inline-flex elsa-items-center elsa-px-4 elsa-py-2 elsa-border elsa-border-gray-300 elsa-text-sm elsa-leading-5 elsa-font-medium elsa-rounded-md elsa-text-gray-700 elsa-bg-white hover:elsa-text-gray-500 focus:elsa-outline-none focus:elsa-shadow-outline-blue focus:elsa-border-blue-300 active:elsa-bg-gray-100 active:elsa-text-gray-700 elsa-transition elsa-ease-in-out elsa-duration-150"> + {fieldLabel} + + + ) + } +} diff --git a/src/designer/elsa-workflows-studio/src/components/screens/workflow-definition-editor/elsa-workflow-definition-editor-screen/elsa-workflow-definition-editor-screen.tsx b/src/designer/elsa-workflows-studio/src/components/screens/workflow-definition-editor/elsa-workflow-definition-editor-screen/elsa-workflow-definition-editor-screen.tsx index fd7ff7e05..35619793f 100644 --- a/src/designer/elsa-workflows-studio/src/components/screens/workflow-definition-editor/elsa-workflow-definition-editor-screen/elsa-workflow-definition-editor-screen.tsx +++ b/src/designer/elsa-workflows-studio/src/components/screens/workflow-definition-editor/elsa-workflow-definition-editor-screen/elsa-workflow-definition-editor-screen.tsx @@ -46,6 +46,7 @@ export class ElsaWorkflowDefinitionEditorScreen { @State() imported: boolean; @State() networkError: string; @State() selectedActivityId?: string; + @State() workflowDesignerMode: WorkflowDesignerMode.Edit; @State() activityContextMenuState: ActivityContextMenuState = { shown: false, @@ -435,7 +436,7 @@ export class ElsaWorkflowDefinitionEditorScreen { return (
this.onActivityContextMenuButtonClicked(e)} onConnectionContextMenuButtonClicked={e => this.onConnectionContextMenuButtonClicked(e)} diff --git a/src/designer/elsa-workflows-studio/src/components/screens/workflow-definition-editor/elsa-workflow-test-panel/elsa-workflow-test-panel.tsx b/src/designer/elsa-workflows-studio/src/components/screens/workflow-definition-editor/elsa-workflow-test-panel/elsa-workflow-test-panel.tsx index 3acd3d243..f54f61cc1 100644 --- a/src/designer/elsa-workflows-studio/src/components/screens/workflow-definition-editor/elsa-workflow-test-panel/elsa-workflow-test-panel.tsx +++ b/src/designer/elsa-workflows-studio/src/components/screens/workflow-definition-editor/elsa-workflow-test-panel/elsa-workflow-test-panel.tsx @@ -1,19 +1,14 @@ -import {Component, Prop, h, Method, State, Watch, Host} from '@stencil/core'; +import {Component, Prop, h, State, Watch, Host} from '@stencil/core'; import {HubConnection, HubConnectionBuilder} from '@microsoft/signalr'; import * as collection from 'lodash/collection'; -import {EventTypes, WorkflowDefinition, WorkflowDefinitionSummary, WorkflowTestActivityMessage, WorkflowTestUpdateRequest} from "../../../../models"; +import {EventTypes, WorkflowDefinition, WorkflowTestActivityMessage, WorkflowTestUpdateRequest} from "../../../../models"; import {i18n} from "i18next"; import {loadTranslations} from "../../../i18n/i18n-loader"; import {resources} from "./localizations"; import {createElsaClient, eventBus, WorkflowTestExecuteRequest} from "../../../../services"; import Tunnel from "../../../../data/dashboard"; import {convert} from 'json-to-json-schema'; - -interface Tab { - id: string; - text: string; - view: () => any; -} +import {clip} from "../../../../utils/utils"; @Component({ tag: 'elsa-workflow-test-panel', @@ -39,7 +34,6 @@ export class ElsaWorkflowTestPanel { @Watch('workflowTestActivityId') async workflowTestActivityMessageChangedHandler(newMessage: string, oldMessage: string) { const message = this.workflowTestActivityMessages.find(x => x.activityId == newMessage); - debugger; this.message = !!message ? message : null; } @@ -84,8 +78,9 @@ export class ElsaWorkflowTestPanel { await elsaClient.workflowTestApi.execute(request); } - async onUseAsSchemaClick() { - const value = this.message.data["Inbound Request"]; + async onUseAsSchemaClick() { + debugger + const value = this.message.data["Body"]; const request: WorkflowTestUpdateRequest = { activityId: this.message.activityId, jsonSchema: JSON.stringify(convert(value), null, 4) @@ -100,11 +95,15 @@ export class ElsaWorkflowTestPanel { return ( - +
+
+ +
+
{this.renderActivityTestMessage()}
); @@ -150,30 +149,33 @@ export class ElsaWorkflowTestPanel { filteredData[key] = valueText; } - const isInboundRequest = dataKey === "Inbound Request"; + const hasBody = dataKey === "Body"; - return ( + return (
-
-
{'Correlation Id'}
-
{message.correlationId}
-
-
-
{t('Status')}
-
{message.status}
-
- {collection.map(filteredData, (v, k) => ( +
+
+
 clip(e.currentTarget)}>{this.serverUrl + '/workflows' + message.path + '?correlation=' + message.correlationId}
+
+
+
+
{t('Status')}
+
{message.status}
+
+ {collection.map(filteredData, (v, k) => (
{k}
{v}
- {isInboundRequest ? - + {hasBody ? +
+ +
: null } diff --git a/src/designer/elsa-workflows-studio/src/drivers/index.ts b/src/designer/elsa-workflows-studio/src/drivers/index.ts index c058d785d..275541886 100644 --- a/src/designer/elsa-workflows-studio/src/drivers/index.ts +++ b/src/designer/elsa-workflows-studio/src/drivers/index.ts @@ -9,3 +9,4 @@ export * from './null-property-driver'; export * from './radio-list-driver'; export * from './single-line-driver'; export * from './switch-case-builder-driver'; +export * from './url-driver'; \ No newline at end of file diff --git a/src/designer/elsa-workflows-studio/src/drivers/url-driver.tsx b/src/designer/elsa-workflows-studio/src/drivers/url-driver.tsx new file mode 100644 index 000000000..5aad77b58 --- /dev/null +++ b/src/designer/elsa-workflows-studio/src/drivers/url-driver.tsx @@ -0,0 +1,12 @@ +import {PropertyDisplayDriver} from "../services"; +import {ActivityModel, ActivityPropertyDescriptor} from "../models"; +import {h} from "@stencil/core"; +import {getOrCreateProperty} from "../utils/utils"; + +export class UrlDriver implements PropertyDisplayDriver { + + display(activity: ActivityModel, property: ActivityPropertyDescriptor) { + const prop = getOrCreateProperty(activity, property.name); + return ; + } +} diff --git a/src/designer/elsa-workflows-studio/src/models/domain.ts b/src/designer/elsa-workflows-studio/src/models/domain.ts index d8ba848a9..2579d6881 100644 --- a/src/designer/elsa-workflows-studio/src/models/domain.ts +++ b/src/designer/elsa-workflows-studio/src/models/domain.ts @@ -324,6 +324,7 @@ export class SyntaxNames { } export interface WorkflowTestActivityMessage { + path?: string; correlationId: string; activityId: string; status: string; diff --git a/src/designer/elsa-workflows-studio/src/plugins/default-drivers-plugin.ts b/src/designer/elsa-workflows-studio/src/plugins/default-drivers-plugin.ts index 8a5f88df3..4279ee907 100644 --- a/src/designer/elsa-workflows-studio/src/plugins/default-drivers-plugin.ts +++ b/src/designer/elsa-workflows-studio/src/plugins/default-drivers-plugin.ts @@ -1,5 +1,5 @@ import {propertyDisplayManager, ElsaPlugin, PropertyDisplayDriver} from "../services"; -import {JsonDriver, RadioListDriver, CheckboxDriver, CheckListDriver, CodeEditorDriver, DropdownDriver, MultilineDriver, MultiTextDriver, SingleLineDriver, SwitchCaseBuilderDriver} from "../drivers"; +import {JsonDriver, RadioListDriver, CheckboxDriver, CheckListDriver, CodeEditorDriver, DropdownDriver, MultilineDriver, MultiTextDriver, SingleLineDriver, SwitchCaseBuilderDriver, UrlDriver} from "../drivers"; import {ElsaStudio} from "../models"; export class DefaultDriversPlugin implements ElsaPlugin { @@ -12,8 +12,9 @@ export class DefaultDriversPlugin implements ElsaPlugin { this.addDriver('checkbox', () => new CheckboxDriver()); this.addDriver('dropdown', () => new DropdownDriver()); this.addDriver('multi-text', () => new MultiTextDriver()); - this.addDriver('code-editor', () => new CodeEditorDriver()); + this.addDriver('code-editor', () => new CodeEditorDriver()); this.addDriver('switch-case-builder', () => new SwitchCaseBuilderDriver()); + this.addDriver('url', () => new UrlDriver()); } addDriver(controlType: string, c: (elsaStudio: ElsaStudio) => T) { diff --git a/src/server/Elsa.Server.Api/Handlers/ActivityExecutionResultExecutedHandler.cs b/src/server/Elsa.Server.Api/Handlers/ActivityExecutionResultExecutedHandler.cs index f7d6c2d5d..b393c487b 100644 --- a/src/server/Elsa.Server.Api/Handlers/ActivityExecutionResultExecutedHandler.cs +++ b/src/server/Elsa.Server.Api/Handlers/ActivityExecutionResultExecutedHandler.cs @@ -1,3 +1,5 @@ +using System; +using System.Linq; using System.Threading; using System.Threading.Tasks; using Elsa.Events; @@ -22,6 +24,7 @@ namespace Elsa.Server.Api.Handlers public async Task Handle(ActivityExecutionResultExecuted notification, CancellationToken cancellationToken) { var context = notification.ActivityExecutionContext; + string? path = default; var signalRConnectionId = context.WorkflowExecutionContext.WorkflowBlueprint.SignalRConnectionId; if (string.IsNullOrWhiteSpace(signalRConnectionId)) return; @@ -31,11 +34,21 @@ namespace Elsa.Server.Api.Handlers ["Outcomes"] = JToken.FromObject(context.Outcomes) }; - foreach (var entry in context.JournalData) - data[entry.Key] = entry.Value != null ? JToken.FromObject(entry.Value) : JValue.CreateNull(); + var body = context.Input != null? ((dynamic)context.Input).Body : null; + + if (body != null) + data["Body"] = JToken.FromObject(body); + + var activityData = context.WorkflowInstance.ActivityData.FirstOrDefault(); + var pathProperty = activityData.Value.FirstOrDefault(x => x.Key == "Path"); + if (pathProperty.Value != null) + { + path = pathProperty.Value.ToString(); + } var message = new WorkflowTestMessage { + Path = path, CorrelationId = context.CorrelationId, ActivityId = context.ActivityId, Status = context.WorkflowExecutionContext.Status == WorkflowStatus.Running diff --git a/src/server/Elsa.Server.Api/Models/WorkflowTestMessage.cs b/src/server/Elsa.Server.Api/Models/WorkflowTestMessage.cs index 21b7f4849..a3ec9359f 100644 --- a/src/server/Elsa.Server.Api/Models/WorkflowTestMessage.cs +++ b/src/server/Elsa.Server.Api/Models/WorkflowTestMessage.cs @@ -2,6 +2,7 @@ namespace Elsa.Server.Api.Models { public class WorkflowTestMessage { + public string? Path { get; set; } public string CorrelationId { get; set; } = default!; public string ActivityId { get; set; } = default!; public string Status { get; set; } = default!;