PR change requests
This commit is contained in:
parent
80ce9995a8
commit
f203e0cdef
|
|
@ -75,10 +75,12 @@ namespace Elsa.Activities.Http.Middleware
|
|||
return;
|
||||
}
|
||||
|
||||
var isTest = pendingWorkflowInstance.GetMetadata("isTest");
|
||||
var workflowBlueprint = (isTest != null && Convert.ToBoolean(isTest)) ?
|
||||
await workflowRegistry.FindAsync(x => x.Id == pendingWorkflowInstance.DefinitionId, cancellationToken) :
|
||||
await workflowRegistry.FindAsync(x => x.IsPublished && x.Id == pendingWorkflowInstance.DefinitionId && !x.IsDisabled, cancellationToken);
|
||||
//var isTest = pendingWorkflowInstance.GetMetadata("isTest");
|
||||
//var workflowBlueprint = (isTest != null && Convert.ToBoolean(isTest)) ?
|
||||
// await workflowRegistry.FindAsync(x => x.Id == pendingWorkflowInstance.DefinitionId, cancellationToken) :
|
||||
// await workflowRegistry.FindAsync(x => x.IsPublished && x.Id == pendingWorkflowInstance.DefinitionId && !x.IsDisabled, cancellationToken);
|
||||
|
||||
var workflowBlueprint = await workflowRegistry.FindActiveAsync(x => x.Id == pendingWorkflowInstance.DefinitionId && !x.IsDisabled, cancellationToken);
|
||||
|
||||
if (workflowBlueprint is null)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -36,5 +36,10 @@ namespace Elsa.Services
|
|||
/// Returns a single workflow blueprint that fits the specified predicate.
|
||||
/// </summary>
|
||||
Task<IWorkflowBlueprint?> FindAsync(Func<IWorkflowBlueprint, bool> predicate, CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
/// Returns a single workflow blueprint that fits the specified predicate.
|
||||
/// </summary>
|
||||
Task<IWorkflowBlueprint?> FindActiveAsync(Func<IWorkflowBlueprint, bool> predicate, CancellationToken cancellationToken = default);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
|
@ -55,6 +55,12 @@ namespace Elsa.Decorators
|
|||
return workflows.FirstOrDefault(predicate);
|
||||
}
|
||||
|
||||
public async Task<IWorkflowBlueprint?> FindActiveAsync(Func<IWorkflowBlueprint, bool> predicate, CancellationToken cancellationToken)
|
||||
{
|
||||
var workflows = await ListActiveAsync(cancellationToken);
|
||||
return workflows.FirstOrDefault(predicate);
|
||||
}
|
||||
|
||||
private async Task<ICollection<IWorkflowBlueprint>> ListInternalAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
return await _memoryCache.GetOrCreateAsync(CacheKey, async entry =>
|
||||
|
|
|
|||
|
|
@ -44,6 +44,9 @@ namespace Elsa.Services.Workflows
|
|||
public async Task<IWorkflowBlueprint?> FindAsync(Func<IWorkflowBlueprint, bool> predicate, CancellationToken cancellationToken) =>
|
||||
(await ListAsync(cancellationToken).Where(predicate).OrderByDescending(x => x.Version)).FirstOrDefault();
|
||||
|
||||
public async Task<IWorkflowBlueprint?> FindActiveAsync(Func<IWorkflowBlueprint, bool> predicate, CancellationToken cancellationToken) =>
|
||||
(await ListActiveAsync(cancellationToken).Where(predicate).OrderByDescending(x => x.Version)).FirstOrDefault();
|
||||
|
||||
private async IAsyncEnumerable<IWorkflowBlueprint> ListActiveInternalAsync([EnumeratorCancellation] CancellationToken cancellationToken)
|
||||
{
|
||||
var workflows = await ListAsync(cancellationToken);
|
||||
|
|
|
|||
|
|
@ -1,9 +1,8 @@
|
|||
import {Component, h, Prop, State} from '@stencil/core';
|
||||
import {ActivityDefinitionProperty, ActivityPropertyDescriptor} from "../../../../models";
|
||||
import {createElsaClient} from "../../../../services";
|
||||
import {ActivityDefinitionProperty, ActivityPropertyDescriptor, ActivityValidatingContext, EventTypes} from "../../../../models";
|
||||
import {createElsaClient, eventBus} from "../../../../services";
|
||||
import Tunnel from '../../../../data/workflow-editor';
|
||||
import {MonacoValueChangedArgs} from "../../../controls/elsa-monaco/elsa-monaco";
|
||||
import Ajv from "ajv"
|
||||
|
||||
@Component({
|
||||
tag: 'elsa-script-property',
|
||||
|
|
@ -19,9 +18,10 @@ export class ElsaScriptProperty {
|
|||
@Prop() syntax?: string;
|
||||
@Prop({mutable: true}) serverUrl: string;
|
||||
@Prop({mutable: true}) workflowDefinitionId: string;
|
||||
@State() currentValue?: string
|
||||
@State() isJsonSchemaValid?: boolean;
|
||||
@State() currentValue?: string;
|
||||
|
||||
monacoEditor: HTMLElsaMonacoElement;
|
||||
private activityValidatingContext: ActivityValidatingContext = null;
|
||||
|
||||
async componentWillLoad() {
|
||||
this.currentValue = this.propertyModel.expressions['Literal'];
|
||||
|
|
@ -49,47 +49,24 @@ export class ElsaScriptProperty {
|
|||
|
||||
onConvertToJsonSchemaClick(e: Event) {
|
||||
e.preventDefault();
|
||||
window.open('https://extendsclass.com/json-schema-validator.html');
|
||||
window.open('https://www.convertsimple.com/convert-json-to-json-schema/');
|
||||
}
|
||||
|
||||
onMonacoValueChanged(e: MonacoValueChangedArgs) {
|
||||
this.currentValue = e.value;
|
||||
this.validate(e.value);
|
||||
this.validate(this.currentValue);
|
||||
}
|
||||
|
||||
validate(value: string) {
|
||||
const propertyDescriptor = this.propertyDescriptor;
|
||||
const propertyName = propertyDescriptor.name;
|
||||
const fieldName = propertyName;
|
||||
|
||||
if (fieldName === "Schema")
|
||||
{
|
||||
this.isJsonSchemaValid = true;
|
||||
if (value == '') return;
|
||||
|
||||
const ajv = new Ajv();
|
||||
let json: object;
|
||||
try{
|
||||
json = JSON.parse(value)
|
||||
}
|
||||
catch (e){
|
||||
this.isJsonSchemaValid = false;
|
||||
}
|
||||
|
||||
if (json != undefined)
|
||||
{
|
||||
try {
|
||||
const validate = ajv.compile(json);
|
||||
const errors = validate.errors;
|
||||
if (errors != null)
|
||||
this.isJsonSchemaValid = false;
|
||||
}
|
||||
catch (e){
|
||||
const err = e;
|
||||
this.isJsonSchemaValid = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
this.activityValidatingContext = {
|
||||
activityType: this.context,
|
||||
prop: this.propertyDescriptor.name,
|
||||
value: value,
|
||||
data: null,
|
||||
isValidated: false,
|
||||
isPositiveResult: false
|
||||
};
|
||||
eventBus.emit(EventTypes.ActivityPluginValidating, this, this.activityValidatingContext);
|
||||
}
|
||||
|
||||
render() {
|
||||
|
|
@ -104,6 +81,22 @@ export class ElsaScriptProperty {
|
|||
const value = this.currentValue;
|
||||
const isSchema = fieldName === "Schema";
|
||||
|
||||
const renderValidationResult = () => {
|
||||
if (this.activityValidatingContext == null || !this.activityValidatingContext.isValidated)
|
||||
return;
|
||||
|
||||
const isPositiveResult = this.activityValidatingContext.isPositiveResult;
|
||||
const color = isPositiveResult ? 'green' : 'red';
|
||||
|
||||
return (
|
||||
<div class="elsa-mt-3">
|
||||
<p class={`elsa-mt-1 elsa-text-sm elsa-text-${color}-500`}>
|
||||
{this.activityValidatingContext.data}
|
||||
</p>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
return <div>
|
||||
|
||||
<div class="elsa-flex">
|
||||
|
|
@ -133,18 +126,10 @@ export class ElsaScriptProperty {
|
|||
ref={el => this.monacoEditor = el}/>
|
||||
</div>
|
||||
{fieldHint ? <p class="elsa-mt-2 elsa-text-sm elsa-text-gray-500">{fieldHint}</p> : undefined}
|
||||
{this.isJsonSchemaValid == undefined ? undefined : this.isJsonSchemaValid ?
|
||||
<p class="elsa-mt-1 elsa-text-sm elsa-text-green-500">
|
||||
Json is valid
|
||||
</p>
|
||||
:
|
||||
<p class="elsa-mt-1 elsa-text-sm elsa-text-red-500">
|
||||
Json is invalid
|
||||
</p>
|
||||
}
|
||||
<input type="hidden" name={fieldName} value={value}/>
|
||||
{renderValidationResult()}
|
||||
{isSchema ?
|
||||
<div class="elsa-mt-1">
|
||||
<div class="elsa-mt-3">
|
||||
<a href="#"
|
||||
onClick={e => this.onConvertToJsonSchemaClick(e)}
|
||||
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">
|
||||
|
|
|
|||
|
|
@ -4,16 +4,15 @@ import {
|
|||
ActivityDefinition,
|
||||
ActivityDescriptor,
|
||||
ActivityModel,
|
||||
ActivityUpdatedContext,
|
||||
ConnectionDefinition,
|
||||
ConnectionModel,
|
||||
EventTypes,
|
||||
SyntaxNames,
|
||||
VersionOptions,
|
||||
WorkflowDefinition,
|
||||
WorkflowModel,
|
||||
WorkflowPersistenceBehavior,
|
||||
WorkflowTestActivityMessage,
|
||||
WorkflowTestUpdateHttpEndpoint
|
||||
WorkflowTestActivityMessage
|
||||
} from "../../../../models";
|
||||
import {createElsaClient, eventBus, SaveWorkflowDefinitionRequest} from "../../../../services";
|
||||
import state from '../../../../utils/store';
|
||||
|
|
@ -447,18 +446,7 @@ export class ElsaWorkflowDefinitionEditorScreen {
|
|||
this.workflowTestActivityMessages = [];
|
||||
|
||||
this.render();
|
||||
};
|
||||
|
||||
async updateHttpEndpointJsonSchema(request: WorkflowTestUpdateHttpEndpoint) {
|
||||
let workflowModel = {...this.workflowModel};
|
||||
const activity = workflowModel.activities.find(x => x.activityId == request.activityId);
|
||||
if (activity)
|
||||
{
|
||||
const activityModel = activity.properties.find(x => x.name == 'Schema');
|
||||
activityModel.expressions[SyntaxNames.Literal] = request.jsonSchema;
|
||||
eventBus.emit(EventTypes.UpdateActivity, this, activityModel);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
private onUpdateWorkflowSettings = async (workflowDefinition: WorkflowDefinition) => {
|
||||
this.updateWorkflowDefinition(workflowDefinition);
|
||||
|
|
@ -588,12 +576,14 @@ export class ElsaWorkflowDefinitionEditorScreen {
|
|||
|
||||
async onUseAsSchemaClick(message: WorkflowTestActivityMessage) {
|
||||
const value = message.data["Body"];
|
||||
const request: WorkflowTestUpdateHttpEndpoint = {
|
||||
activityId: message.activityId,
|
||||
jsonSchema: JSON.stringify(convert(value), null, 1)
|
||||
};
|
||||
let workflowModel = {...this.workflowModel};
|
||||
const activityModel = workflowModel.activities.find(x => x.activityId == message.activityId);
|
||||
|
||||
await this.updateHttpEndpointJsonSchema(request);
|
||||
const context: ActivityUpdatedContext = {
|
||||
activityModel: activityModel,
|
||||
data: JSON.stringify(convert(value), null, 1)
|
||||
};
|
||||
eventBus.emit(EventTypes.ActivityPluginUpdated, this, context);
|
||||
}
|
||||
|
||||
renderTestActivityMenu = () => {
|
||||
|
|
|
|||
|
|
@ -334,11 +334,6 @@ export interface WorkflowTestActivityMessage {
|
|||
error?: string;
|
||||
}
|
||||
|
||||
export interface WorkflowTestUpdateHttpEndpoint {
|
||||
activityId?: string,
|
||||
jsonSchema?: string
|
||||
}
|
||||
|
||||
export const getVersionOptionsString = (versionOptions?: VersionOptions) => {
|
||||
|
||||
if (!versionOptions)
|
||||
|
|
|
|||
|
|
@ -15,6 +15,8 @@ export const EventTypes = {
|
|||
WorkflowModelChanged: 'workflow-model-changed',
|
||||
ActivityDesignDisplaying: 'activity-design-displaying',
|
||||
ActivityDescriptorDisplaying: 'activity-descriptor-displaying',
|
||||
ActivityPluginUpdated: 'activity-plugin-updated',
|
||||
ActivityPluginValidating: 'activity-plugin-validating',
|
||||
WorkflowPublished: 'workflow-published',
|
||||
WorkflowRetracted: 'workflow-retracted',
|
||||
WorkflowImported: 'workflow-imported',
|
||||
|
|
@ -57,6 +59,20 @@ export interface ActivityDesignDisplayContext {
|
|||
outcomes: Array<string>;
|
||||
}
|
||||
|
||||
export interface ActivityUpdatedContext {
|
||||
activityModel: ActivityModel,
|
||||
data?: string
|
||||
}
|
||||
|
||||
export interface ActivityValidatingContext {
|
||||
activityType: string
|
||||
prop: string,
|
||||
value?: string,
|
||||
isValidated: boolean,
|
||||
data: any,
|
||||
isPositiveResult: boolean
|
||||
}
|
||||
|
||||
export interface ActivityDescriptorDisplayContext {
|
||||
activityDescriptor: ActivityDescriptor;
|
||||
activityIcon: any;
|
||||
|
|
|
|||
|
|
@ -1,11 +1,13 @@
|
|||
import {eventBus, ElsaPlugin} from "../services";
|
||||
import {ActivityDesignDisplayContext, EventTypes, SyntaxNames} from "../models";
|
||||
import {h} from "@stencil/core";
|
||||
import {ActivityDesignDisplayContext, ActivityUpdatedContext, ActivityValidatingContext, EventTypes, SyntaxNames} from "../models";
|
||||
import {htmlEncode} from "../utils/utils";
|
||||
import Ajv from "ajv"
|
||||
|
||||
export class HttpEndpointPlugin implements ElsaPlugin {
|
||||
constructor() {
|
||||
eventBus.on(EventTypes.ActivityDesignDisplaying, this.onActivityDisplaying);
|
||||
eventBus.on(EventTypes.ActivityPluginUpdated, this.onActivityUpdated);
|
||||
eventBus.on(EventTypes.ActivityPluginValidating, this.onActivityValidating);
|
||||
}
|
||||
|
||||
onActivityDisplaying(context: ActivityDesignDisplayContext) {
|
||||
|
|
@ -20,4 +22,53 @@ export class HttpEndpointPlugin implements ElsaPlugin {
|
|||
const bodyDisplay = htmlEncode(path.expressions[syntax]);
|
||||
context.bodyDisplay = `<p>${bodyDisplay}</p>`;
|
||||
}
|
||||
|
||||
onActivityUpdated(context: ActivityUpdatedContext) {
|
||||
const activityModel = context.activityModel;
|
||||
if (activityModel.type !== 'HttpEndpoint')
|
||||
return;
|
||||
|
||||
const props = activityModel.properties || [];
|
||||
const prop = props.find(x => x.name == 'Schema') || { name: 'Schema', expressions: { 'Literal': '', syntax: SyntaxNames.Literal } };
|
||||
prop.expressions[SyntaxNames.Literal] = context.data;
|
||||
eventBus.emit(EventTypes.UpdateActivity, this, prop);
|
||||
}
|
||||
|
||||
onActivityValidating(context: ActivityValidatingContext) {
|
||||
|
||||
if (context.activityType !== 'HttpEndpoint' || context.prop !== 'Schema')
|
||||
return;
|
||||
|
||||
const jsonSchema = context.value;
|
||||
let isValid = true;
|
||||
|
||||
if (jsonSchema == '') return;
|
||||
|
||||
const ajv = new Ajv();
|
||||
let json: object;
|
||||
try{
|
||||
json = JSON.parse(jsonSchema)
|
||||
}
|
||||
catch (e){
|
||||
isValid = false;
|
||||
}
|
||||
|
||||
if (json != undefined)
|
||||
{
|
||||
try {
|
||||
const validate = ajv.compile(json);
|
||||
const errors = validate.errors;
|
||||
if (errors != null)
|
||||
isValid = false;
|
||||
}
|
||||
catch (e){
|
||||
const err = e;
|
||||
isValid = false;
|
||||
}
|
||||
}
|
||||
|
||||
context.isValidated = true;
|
||||
context.isPositiveResult = isValid;
|
||||
context.data = isValid ? 'Json is valid' : 'Json is invalid';
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
using System;
|
||||
using System.Linq;
|
||||
using Elsa;
|
||||
using Elsa.Models;
|
||||
using Elsa.Server.Api;
|
||||
|
|
@ -7,6 +6,7 @@ using Elsa.Server.Api.Handlers;
|
|||
using Elsa.Server.Api.Mapping;
|
||||
using Elsa.Server.Api.Services;
|
||||
using Elsa.Server.Api.Swagger.Examples;
|
||||
using Elsa.Services;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.OpenApi.Any;
|
||||
using Microsoft.OpenApi.Models;
|
||||
|
|
@ -48,14 +48,15 @@ namespace Microsoft.Extensions.DependencyInjection
|
|||
options.AssumeDefaultVersionWhenUnspecified = true;
|
||||
});
|
||||
|
||||
services.AddSingleton<ConnectionConverter>();
|
||||
services.AddSingleton<ActivityBlueprintConverter>();
|
||||
services.AddScoped<IWorkflowBlueprintMapper, WorkflowBlueprintMapper>();
|
||||
services.AddScoped<IWorkflowTestService, WorkflowTestService>();
|
||||
services.AddSingleton<IEndpointContentSerializerSettingsProvider, EndpointContentSerializerSettingsProvider>();
|
||||
services.AddAutoMapperProfile<AutoMapperProfile>();
|
||||
services.AddNotificationHandlersFrom<ActivityExecutionResultExecutedHandler>();
|
||||
services.AddSignalR();
|
||||
services
|
||||
.AddSingleton<ConnectionConverter>()
|
||||
.AddSingleton<ActivityBlueprintConverter>()
|
||||
.AddScoped<IWorkflowBlueprintMapper, WorkflowBlueprintMapper>()
|
||||
.AddScoped<IWorkflowTestService, WorkflowTestService>()
|
||||
.AddSingleton<IEndpointContentSerializerSettingsProvider, EndpointContentSerializerSettingsProvider>()
|
||||
.AddAutoMapperProfile<AutoMapperProfile>()
|
||||
.AddNotificationHandlersFrom<ActivityExecutionResultExecutedHandler>()
|
||||
.AddSignalR();
|
||||
return services;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue