fixes
This commit is contained in:
parent
1f4f5f695b
commit
04bacaa281
|
|
@ -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 },
|
||||
|
|
|
|||
|
|
@ -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";
|
||||
|
||||
/// <summary>
|
||||
/// An editor that allows the user to write a blob of JSON.
|
||||
|
|
|
|||
|
|
@ -228,6 +228,10 @@ export namespace Components {
|
|||
"hide": () => Promise<void>;
|
||||
"show": (options: ToastNotificationOptions) => Promise<void>;
|
||||
}
|
||||
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<HTMLElsaTabContentElement>;
|
||||
"elsa-tab-header": LocalJSX.ElsaTabHeader & JSXBase.HTMLAttributes<HTMLElsaTabHeaderElement>;
|
||||
"elsa-toast-notification": LocalJSX.ElsaToastNotification & JSXBase.HTMLAttributes<HTMLElsaToastNotificationElement>;
|
||||
"elsa-url-property": LocalJSX.ElsaUrlProperty & JSXBase.HTMLAttributes<HTMLElsaUrlPropertyElement>;
|
||||
"elsa-webhook-definition-editor-notifications": LocalJSX.ElsaWebhookDefinitionEditorNotifications & JSXBase.HTMLAttributes<HTMLElsaWebhookDefinitionEditorNotificationsElement>;
|
||||
"elsa-webhook-definition-editor-screen": LocalJSX.ElsaWebhookDefinitionEditorScreen & JSXBase.HTMLAttributes<HTMLElsaWebhookDefinitionEditorScreenElement>;
|
||||
"elsa-webhook-definitions-list-screen": LocalJSX.ElsaWebhookDefinitionsListScreen & JSXBase.HTMLAttributes<HTMLElsaWebhookDefinitionsListScreenElement>;
|
||||
|
|
|
|||
|
|
@ -3,7 +3,8 @@
|
|||
export enum WorkflowDesignerMode {
|
||||
Edit,
|
||||
Instance,
|
||||
Blueprint
|
||||
Blueprint,
|
||||
Test
|
||||
}
|
||||
|
||||
export interface ActivityContextMenuState {
|
||||
|
|
|
|||
|
|
@ -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 (
|
||||
<elsa-property-editor propertyDescriptor={propertyDescriptor}
|
||||
propertyModel={propertyModel}
|
||||
single-line={true}
|
||||
showLabel={false}>
|
||||
<a href="#"
|
||||
onClick={e => 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}
|
||||
</a>
|
||||
</elsa-property-editor>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -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 (
|
||||
<div class="elsa-flex-1 elsa-flex elsa-relative">
|
||||
<elsa-designer-tree model={this.workflowModel}
|
||||
mode={WorkflowDesignerMode.Edit}
|
||||
mode={this.workflowDesignerMode}
|
||||
activityContextMenuButton={activityContextMenuButton}
|
||||
onActivityContextMenuButtonClicked={e => this.onActivityContextMenuButtonClicked(e)}
|
||||
onConnectionContextMenuButtonClicked={e => this.onConnectionContextMenuButtonClicked(e)}
|
||||
|
|
|
|||
|
|
@ -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 (
|
||||
<Host>
|
||||
<button type="button"
|
||||
onClick={() => this.onExecuteWorkflowClick()}
|
||||
class="elsa-ml-0 elsa-w-full elsa-inline-flex elsa-justify-center elsa-rounded-md elsa-border elsa-border-transparent elsa-shadow-sm elsa-px-4 elsa-py-2 elsa-bg-blue-600 elsa-text-base elsa-font-medium elsa-text-white hover:elsa-bg-blue-700 focus:elsa-outline-none focus:elsa-ring-2 focus:elsa-ring-offset-2 focus:elsa-ring-blue-500 sm:elsa-ml-3 sm:elsa-w-auto sm:elsa-text-sm">
|
||||
{t('ExecuteWorkflow')}
|
||||
</button>
|
||||
<dl class="elsa-border-b elsa-border-gray-200 elsa-divide-y elsa-divide-gray-200">
|
||||
<div class="elsa-py-3 elsa-flex elsa-justify-between elsa-text-sm elsa-font-medium">
|
||||
<button type="button"
|
||||
onClick={() => this.onExecuteWorkflowClick()}
|
||||
class="elsa-ml-0 elsa-w-full elsa-inline-flex elsa-justify-center elsa-rounded-md elsa-border elsa-border-transparent elsa-shadow-sm elsa-px-4 elsa-py-2 elsa-bg-blue-600 elsa-text-base elsa-font-medium elsa-text-white hover:elsa-bg-blue-700 focus:elsa-outline-none focus:elsa-ring-2 focus:elsa-ring-offset-2 focus:elsa-ring-blue-500 sm:elsa-ml-3 sm:elsa-w-auto sm:elsa-text-sm">
|
||||
{t('ExecuteWorkflow')}
|
||||
</button>
|
||||
</div>
|
||||
</dl>
|
||||
{this.renderActivityTestMessage()}
|
||||
</Host>
|
||||
);
|
||||
|
|
@ -150,30 +149,33 @@ export class ElsaWorkflowTestPanel {
|
|||
filteredData[key] = valueText;
|
||||
}
|
||||
|
||||
const isInboundRequest = dataKey === "Inbound Request";
|
||||
const hasBody = dataKey === "Body";
|
||||
|
||||
return (
|
||||
return (
|
||||
<dl class="elsa-border-b elsa-border-gray-200 elsa-divide-y elsa-divide-gray-200">
|
||||
<div class="elsa-py-3 elsa-flex elsa-justify-between elsa-text-sm elsa-font-medium">
|
||||
<dt class="elsa-text-gray-500">{'Correlation Id'}</dt>
|
||||
<dd class="elsa-text-gray-900">{message.correlationId}</dd>
|
||||
</div>
|
||||
<div class="elsa-py-3 elsa-flex elsa-justify-between elsa-text-sm elsa-font-medium">
|
||||
<dt class="elsa-text-gray-500">{t('Status')}</dt>
|
||||
<dd class="elsa-text-gray-900">{message.status}</dd>
|
||||
</div>
|
||||
{collection.map(filteredData, (v, k) => (
|
||||
<div class="elsa-py-3 elsa-flex elsa-justify-between elsa-text-sm elsa-font-medium">
|
||||
<dt class="elsa-text-gray-500">
|
||||
<pre onClick={e => clip(e.currentTarget)}>{this.serverUrl + '/workflows' + message.path + '?correlation=' + message.correlationId}</pre>
|
||||
</dt>
|
||||
</div>
|
||||
<div class="elsa-py-3 elsa-flex elsa-justify-between elsa-text-sm elsa-font-medium">
|
||||
<dt class="elsa-text-gray-500">{t('Status')}</dt>
|
||||
<dd class="elsa-text-gray-900">{message.status}</dd>
|
||||
</div>
|
||||
{collection.map(filteredData, (v, k) => (
|
||||
<div>
|
||||
<div class="elsa-py-3 elsa-flex elsa-justify-between elsa-text-sm elsa-font-medium">
|
||||
<dt class="elsa-text-gray-500">{k}</dt>
|
||||
<dd class="elsa-mt-1 elsa-text-sm elsa-text-gray-900 elsa-mb-2 elsa-overflow-x-auto">{v}</dd>
|
||||
</div>
|
||||
{isInboundRequest ?
|
||||
<button type="button"
|
||||
onClick={() => this.onUseAsSchemaClick()}
|
||||
class="elsa-ml-0 elsa-w-full elsa-inline-flex elsa-justify-center elsa-rounded-md elsa-border elsa-border-transparent elsa-shadow-sm elsa-px-4 elsa-py-2 elsa-bg-blue-600 elsa-text-base elsa-font-medium elsa-text-white hover:elsa-bg-blue-700 focus:elsa-outline-none focus:elsa-ring-2 focus:elsa-ring-offset-2 focus:elsa-ring-blue-500 sm:elsa-ml-3 sm:elsa-w-auto sm:elsa-text-sm">
|
||||
{t('UseAsSchema')}
|
||||
</button>
|
||||
{hasBody ?
|
||||
<div class="elsa-py-3 elsa-flex elsa-justify-between elsa-text-sm elsa-font-medium">
|
||||
<button type="button"
|
||||
onClick={() => this.onUseAsSchemaClick()}
|
||||
class="elsa-ml-0 elsa-w-full elsa-inline-flex elsa-justify-center elsa-rounded-md elsa-border elsa-border-transparent elsa-shadow-sm elsa-px-4 elsa-py-2 elsa-bg-blue-600 elsa-text-base elsa-font-medium elsa-text-white hover:elsa-bg-blue-700 focus:elsa-outline-none focus:elsa-ring-2 focus:elsa-ring-offset-2 focus:elsa-ring-blue-500 sm:elsa-ml-3 sm:elsa-w-auto sm:elsa-text-sm">
|
||||
{t('UseAsSchema')}
|
||||
</button>
|
||||
</div>
|
||||
:
|
||||
null
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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';
|
||||
|
|
@ -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 <elsa-url-property propertyDescriptor={property} propertyModel={prop}/>;
|
||||
}
|
||||
}
|
||||
|
|
@ -324,6 +324,7 @@ export class SyntaxNames {
|
|||
}
|
||||
|
||||
export interface WorkflowTestActivityMessage {
|
||||
path?: string;
|
||||
correlationId: string;
|
||||
activityId: string;
|
||||
status: string;
|
||||
|
|
|
|||
|
|
@ -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<T extends PropertyDisplayDriver>(controlType: string, c: (elsaStudio: ElsaStudio) => T) {
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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!;
|
||||
|
|
|
|||
Loading…
Reference in a new issue