Add While activity (#110)
* Implement While activity * Variable scope bug fixes * Merge designer attributes with activity definition * Update package references
This commit is contained in:
parent
06412c0cc0
commit
cb25239fd1
|
|
@ -13,11 +13,8 @@ namespace Elsa.Activities.Console.Activities
|
|||
/// </summary>
|
||||
[ActivityDefinition(
|
||||
Category = "Console",
|
||||
Description = "Read text from standard in."
|
||||
)]
|
||||
[ActivityDefinitionDesigner(
|
||||
Description =
|
||||
"a => !!a.state.variableName ? `Read text from standard in and store into <strong>${ a.state.variableName }</strong>.` : 'Read text from standard in.'",
|
||||
Description = "Read text from standard in.",
|
||||
RuntimeDescription = "a => !!a.state.variableName ? `Read text from standard in and store into <strong>${ a.state.variableName }</strong>.` : 'Read text from standard in.'",
|
||||
Outcomes = new[] { OutcomeNames.Done }
|
||||
)]
|
||||
public class ReadLine : Activity
|
||||
|
|
|
|||
|
|
@ -15,11 +15,8 @@ namespace Elsa.Activities.Console.Activities
|
|||
/// </summary>
|
||||
[ActivityDefinition(
|
||||
Category = "Console",
|
||||
Description = "Write text to standard out."
|
||||
)]
|
||||
[ActivityDefinitionDesigner(
|
||||
Description =
|
||||
"x => !!x.state.textExpression ? `Write <strong>${ x.state.textExpression.expression }</strong> to standard out.` : x.definition.description",
|
||||
Description = "Write text to standard out.",
|
||||
RuntimeDescription = "x => !!x.state.textExpression ? `Write <strong>${ x.state.textExpression.expression }</strong> to standard out.` : x.definition.description",
|
||||
Outcomes = new[] { OutcomeNames.Done }
|
||||
)]
|
||||
public class WriteLine : Activity
|
||||
|
|
|
|||
|
|
@ -17,8 +17,4 @@
|
|||
<ProjectReference Include="..\..\core\Elsa.Core\Elsa.Core.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.CSharp" Version="4.5.0" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@
|
|||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Extensions.Http" Version="2.2.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Http" Version="3.0.0" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
|
|||
|
|
@ -23,11 +23,8 @@ namespace Elsa.Activities.Http.Activities
|
|||
[ActivityDefinition(
|
||||
Category = "HTTP",
|
||||
DisplayName = "Send HTTP Request",
|
||||
Description = "Send an HTTP request."
|
||||
)]
|
||||
[ActivityDefinitionDesigner(
|
||||
Description =
|
||||
"x => !!x.state.url ? `Send HTTP <strong>${ x.state.method } ${ x.state.url.expression }</strong>.` : x.definition.description",
|
||||
Description = "Send an HTTP request.",
|
||||
RuntimeDescription = "x => !!x.state.url ? `Send HTTP <strong>${ x.state.method } ${ x.state.url.expression }</strong>.` : x.definition.description",
|
||||
Outcomes = "x => !!x.state.supportedStatusCodes ? x.state.supportedStatusCodes : []"
|
||||
)]
|
||||
public class HttpRequestAction : Activity
|
||||
|
|
|
|||
|
|
@ -20,11 +20,8 @@ namespace Elsa.Activities.Http.Activities
|
|||
[ActivityDefinition(
|
||||
Category = "HTTP",
|
||||
DisplayName = "Receive HTTP Request",
|
||||
Description = "Receive an incoming HTTP request."
|
||||
)]
|
||||
[ActivityDefinitionDesigner(
|
||||
Description =
|
||||
"x => !!x.state.path ? `Handle <strong>${ x.state.method } ${ x.state.path }</strong>.` : x.definition.description",
|
||||
Description = "Receive an incoming HTTP request.",
|
||||
RuntimeDescription = "x => !!x.state.path ? `Handle <strong>${ x.state.method } ${ x.state.path }</strong>.` : x.definition.description",
|
||||
Outcomes = new[] { OutcomeNames.Done }
|
||||
)]
|
||||
public class HttpRequestEvent : Activity
|
||||
|
|
|
|||
|
|
@ -18,11 +18,8 @@ namespace Elsa.Activities.Http.Activities
|
|||
[ActivityDefinition(
|
||||
Category = "HTTP",
|
||||
DisplayName = "Send HTTP Response",
|
||||
Description = "Send an HTTP response."
|
||||
)]
|
||||
[ActivityDefinitionDesigner(
|
||||
Description =
|
||||
"x => !!x.state.statusCode ? `Send an HTTP <strong>${ x.state.statusCode }</strong> - <strong>${ x.state.contentType }</strong> response` : x.definition.description",
|
||||
Description = "Send an HTTP response.",
|
||||
RuntimeDescription = "x => !!x.state.statusCode ? `Send an HTTP <strong>${ x.state.statusCode }</strong> - <strong>${ x.state.contentType }</strong> response` : x.definition.description",
|
||||
Outcomes = new[] { OutcomeNames.Done }
|
||||
)]
|
||||
public class HttpResponseAction : Activity
|
||||
|
|
|
|||
|
|
@ -19,11 +19,11 @@
|
|||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="LanguageExt.Core" Version="3.3.29" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.DataProtection" Version="2.2.0" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.DataProtection" Version="3.0.0" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Http" Version="2.2.2" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Http.Abstractions" Version="2.2.0" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Mvc.Core" Version="2.2.5" />
|
||||
<PackageReference Include="Microsoft.Extensions.Http" Version="2.2.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Http" Version="3.0.0" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
|
|||
|
|
@ -14,9 +14,9 @@
|
|||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="MassTransit.AspNetCore" Version="5.5.2" />
|
||||
<PackageReference Include="MassTransit.Extensions.DependencyInjection" Version="5.5.2" />
|
||||
<PackageReference Include="MassTransit.RabbitMQ" Version="5.5.2" />
|
||||
<PackageReference Include="MassTransit.AspNetCore" Version="5.5.6" />
|
||||
<PackageReference Include="MassTransit.Extensions.DependencyInjection" Version="5.5.6" />
|
||||
<PackageReference Include="MassTransit.RabbitMQ" Version="5.5.6" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
|
|
|||
|
|
@ -13,11 +13,8 @@ namespace Elsa.Activities.Timers.Activities
|
|||
{
|
||||
[ActivityDefinition(
|
||||
Category = "Timers",
|
||||
Description = "Triggers periodically based on a specified CRON expression."
|
||||
)]
|
||||
[ActivityDefinitionDesigner(
|
||||
Description =
|
||||
"x => !!x.state.cronExpression ? `<strong>${ x.state.cronExpression.expression }</strong>.` : x.definition.description",
|
||||
Description = "Triggers periodically based on a specified CRON expression.",
|
||||
RuntimeDescription = "x => !!x.state.cronExpression ? `<strong>${ x.state.cronExpression.expression }</strong>.` : x.definition.description",
|
||||
Outcomes = new[] { OutcomeNames.Done }
|
||||
)]
|
||||
public class CronEvent : Activity
|
||||
|
|
@ -43,7 +40,7 @@ namespace Elsa.Activities.Timers.Activities
|
|||
get => GetState<Instant?>();
|
||||
set => SetState(value);
|
||||
}
|
||||
|
||||
|
||||
protected override async Task<bool> OnCanExecuteAsync(WorkflowExecutionContext context, CancellationToken cancellationToken)
|
||||
{
|
||||
return StartTime == null || await IsExpiredAsync(context, cancellationToken);
|
||||
|
|
@ -54,7 +51,8 @@ namespace Elsa.Activities.Timers.Activities
|
|||
return Halt();
|
||||
}
|
||||
|
||||
protected override async Task<ActivityExecutionResult> OnResumeAsync(WorkflowExecutionContext context,
|
||||
protected override async Task<ActivityExecutionResult> OnResumeAsync(
|
||||
WorkflowExecutionContext context,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
if (await IsExpiredAsync(context, cancellationToken))
|
||||
|
|
@ -62,11 +60,12 @@ namespace Elsa.Activities.Timers.Activities
|
|||
StartTime = null;
|
||||
return Done();
|
||||
}
|
||||
|
||||
|
||||
return Halt();
|
||||
}
|
||||
|
||||
private async Task<bool> IsExpiredAsync(WorkflowExecutionContext workflowContext,
|
||||
private async Task<bool> IsExpiredAsync(
|
||||
WorkflowExecutionContext workflowContext,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
var cronExpression = await expressionEvaluator.EvaluateAsync(
|
||||
|
|
@ -76,10 +75,10 @@ namespace Elsa.Activities.Timers.Activities
|
|||
);
|
||||
var schedule = CrontabSchedule.Parse(cronExpression);
|
||||
var now = clock.GetCurrentInstant();
|
||||
|
||||
|
||||
if (StartTime == null)
|
||||
StartTime = now;
|
||||
|
||||
|
||||
var nextOccurrence = schedule.GetNextOccurrence(StartTime.Value.ToDateTimeUtc());
|
||||
|
||||
return now.ToDateTimeUtc() >= nextOccurrence;
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@
|
|||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Extensions.Hosting.Abstractions" Version="2.2.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Hosting.Abstractions" Version="3.0.0" />
|
||||
<PackageReference Include="NCrontab" Version="3.3.1" />
|
||||
</ItemGroup>
|
||||
|
||||
|
|
|
|||
|
|
@ -8,7 +8,9 @@ namespace Elsa.Attributes
|
|||
public string Type { get; set; }
|
||||
public string DisplayName { get; set; }
|
||||
public string Description { get; set; }
|
||||
public string RuntimeDescription { get; set; }
|
||||
public string Category { get; set; }
|
||||
public string Icon { get; set; }
|
||||
public object Outcomes { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
using System;
|
||||
|
||||
namespace Elsa.Attributes
|
||||
{
|
||||
[AttributeUsage(AttributeTargets.Class)]
|
||||
public class ActivityDefinitionDesignerAttribute : Attribute
|
||||
{
|
||||
public string Description { get; set; }
|
||||
public object Outcomes { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
@ -15,7 +15,7 @@
|
|||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Jint" Version="3.0.0-beta-1612" />
|
||||
<PackageReference Include="Jint" Version="3.0.0-beta-1629" />
|
||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="3.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Localization.Abstractions" Version="3.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Primitives" Version="3.0.0" />
|
||||
|
|
|
|||
|
|
@ -25,6 +25,8 @@ namespace Elsa.Models
|
|||
|
||||
public string Id { get; set; }
|
||||
public string Type { get; set; }
|
||||
public string DisplayName { get; set; }
|
||||
public string Description { get; set; }
|
||||
public int Left { get; set; }
|
||||
public int Top { get; set; }
|
||||
public JObject State { get; set; }
|
||||
|
|
|
|||
|
|
@ -7,5 +7,6 @@ namespace Elsa
|
|||
public const string True = "True";
|
||||
public const string False = "False";
|
||||
public const string Iterate = "Iterate";
|
||||
public const string Loop = "Loop";
|
||||
}
|
||||
}
|
||||
|
|
@ -13,7 +13,10 @@ namespace Elsa.Services
|
|||
IOutcomeBuilder When(string outcome);
|
||||
IActivityBuilder Then<T>(Action<T> setup = null, Action<IActivityBuilder> branch = null, string id = null) where T : class, IActivity;
|
||||
IActivityBuilder WithId(string id);
|
||||
IActivityBuilder WithDisplayName(string displayName);
|
||||
IActivityBuilder WithDescription(string description);
|
||||
IWorkflowBuilder Then(string activityId);
|
||||
IActivityBuilder Then(IActivityBuilder targetActivity);
|
||||
WorkflowDefinitionVersion Build();
|
||||
ActivityDefinition BuildActivity();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,8 +12,7 @@ namespace Elsa.Services.Models
|
|||
{
|
||||
public Workflow(
|
||||
string id,
|
||||
string definitionId,
|
||||
int version,
|
||||
WorkflowDefinitionVersion definition,
|
||||
Instant createdAt,
|
||||
IEnumerable<IActivity> activities,
|
||||
IEnumerable<Connection> connections,
|
||||
|
|
@ -21,8 +20,7 @@ namespace Elsa.Services.Models
|
|||
string correlationId = default) : this()
|
||||
{
|
||||
Id = id;
|
||||
DefinitionId = definitionId;
|
||||
Version = version;
|
||||
Definition = definition;
|
||||
CreatedAt = createdAt;
|
||||
CorrelationId = correlationId;
|
||||
Activities = activities.ToList();
|
||||
|
|
@ -30,6 +28,8 @@ namespace Elsa.Services.Models
|
|||
Input = new Variables(input ?? Variables.Empty);
|
||||
}
|
||||
|
||||
|
||||
|
||||
public Workflow()
|
||||
{
|
||||
Scopes = new Stack<WorkflowExecutionScope>(new[] { new WorkflowExecutionScope() });
|
||||
|
|
@ -38,8 +38,7 @@ namespace Elsa.Services.Models
|
|||
}
|
||||
|
||||
public string Id { get; set; }
|
||||
public string DefinitionId { get; }
|
||||
public int Version { get; }
|
||||
public WorkflowDefinitionVersion Definition { get; }
|
||||
public string CorrelationId { get; set; }
|
||||
public WorkflowStatus Status { get; set; }
|
||||
public Instant CreatedAt { get; set; }
|
||||
|
|
@ -63,8 +62,8 @@ namespace Elsa.Services.Models
|
|||
return new WorkflowInstance
|
||||
{
|
||||
Id = Id,
|
||||
DefinitionId = DefinitionId,
|
||||
Version = Version,
|
||||
DefinitionId = Definition.Id,
|
||||
Version = Definition.Version,
|
||||
CorrelationId = CorrelationId,
|
||||
Status = Status,
|
||||
CreatedAt = CreatedAt,
|
||||
|
|
|
|||
|
|
@ -53,8 +53,21 @@ namespace Elsa.Services.Models
|
|||
public IActivity PopScheduledActivity() => CurrentActivity = scheduledActivities.Pop();
|
||||
public void ScheduleHaltingActivity(IActivity activity) => scheduledHaltingActivities.Push(activity);
|
||||
public IActivity PopScheduledHaltingActivity() => scheduledHaltingActivities.Pop();
|
||||
public void SetVariable(string name, object value) => CurrentScope.SetVariable(name, value);
|
||||
public T GetVariable<T>(string name) => CurrentScope.GetVariable<T>(name);
|
||||
|
||||
public void SetVariable(string name, object value)
|
||||
{
|
||||
// Get the first scope (starting from the oldest one) containing the variable (existing variable). Otherwise use the current scope (new variable declaration)
|
||||
var scope = Workflow.Scopes.Reverse().FirstOrDefault(x => x.Variables.ContainsKey(name)) ?? CurrentScope;
|
||||
scope.SetVariable(name, value);
|
||||
}
|
||||
|
||||
public T GetVariable<T>(string name)
|
||||
{
|
||||
// Get the first scope (starting from the newest one) containing the variable.
|
||||
var scope = Workflow.Scopes.FirstOrDefault(x => x.Variables.ContainsKey(name)) ?? CurrentScope;
|
||||
return scope.GetVariable<T>(name);
|
||||
}
|
||||
|
||||
public void SetLastResult(object value) => CurrentScope.LastResult = value;
|
||||
|
||||
public void Start()
|
||||
|
|
|
|||
|
|
@ -14,9 +14,9 @@
|
|||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="AutoMapper" Version="8.1.1" />
|
||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="2.2.0" />
|
||||
<PackageReference Include="NodaTime" Version="2.4.5" />
|
||||
<PackageReference Include="AutoMapper" Version="9.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="3.0.0" />
|
||||
<PackageReference Include="NodaTime" Version="3.0.0-beta01" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
|
|||
|
|
@ -9,8 +9,8 @@ namespace Elsa.Activities.ControlFlow
|
|||
[ActivityDefinition(
|
||||
Category = "Control Flow",
|
||||
Description = "Fork workflow execution into multiple branches.",
|
||||
Icon = "fas fa-code-branch fa-rotate-180")]
|
||||
[ActivityDefinitionDesigner(Outcomes = "x => x.state.branches")]
|
||||
Icon = "fas fa-code-branch fa-rotate-180",
|
||||
Outcomes = "x => x.state.branches")]
|
||||
public class Fork : Activity
|
||||
{
|
||||
[ActivityProperty(
|
||||
|
|
|
|||
|
|
@ -12,11 +12,8 @@ namespace Elsa.Activities.ControlFlow
|
|||
[ActivityDefinition(
|
||||
DisplayName = "If/Else",
|
||||
Category = "Control Flow",
|
||||
Description = "Evaluate a Boolean expression and continue execution depending on the result."
|
||||
)]
|
||||
[ActivityDefinitionDesigner(
|
||||
Description =
|
||||
"x => !!x.state.expression ? `Evaluate <strong>${ x.state.expression.expression }</strong> and continue execution depending on the result.` : x.definition.description",
|
||||
Description = "Evaluate a Boolean expression and continue execution depending on the result.",
|
||||
RuntimeDescription = "x => !!x.state.expression ? `Evaluate <strong>${ x.state.expression.expression }</strong> and continue execution depending on the result.` : x.definition.description",
|
||||
Outcomes = new[] { OutcomeNames.True, OutcomeNames.False }
|
||||
)]
|
||||
public class IfElse : Activity
|
||||
|
|
|
|||
|
|
@ -14,11 +14,8 @@ namespace Elsa.Activities.ControlFlow
|
|||
[ActivityDefinition(
|
||||
Category = "Control Flow",
|
||||
Description = "Merge workflow execution back into a single branch.",
|
||||
Icon = "fas fa-code-branch"
|
||||
)]
|
||||
[ActivityDefinitionDesigner(
|
||||
Description =
|
||||
"x => !!x.state.joinMode ? `Merge workflow execution back into a single branch using mode <strong>${ x.state.joinMode }</strong>` : x.definition.description",
|
||||
Icon = "fas fa-code-branch",
|
||||
RuntimeDescription = "x => !!x.state.joinMode ? `Merge workflow execution back into a single branch using mode <strong>${ x.state.joinMode }</strong>` : x.definition.description",
|
||||
Outcomes = new[] { OutcomeNames.Done }
|
||||
)]
|
||||
public class Join : Activity, IWorkflowEventHandler
|
||||
|
|
|
|||
|
|
@ -13,11 +13,8 @@ namespace Elsa.Activities.ControlFlow
|
|||
[ActivityDefinition(
|
||||
Category = "Control Flow",
|
||||
Description = "Switch execution based on a given expression.",
|
||||
Icon = "far fa-list-alt"
|
||||
)]
|
||||
[ActivityDefinitionDesigner(
|
||||
Description =
|
||||
"x => !!x.state.expression ? `Switch execution based on <strong>${ x.state.expression.expression }</strong>.` : x.definition.description",
|
||||
Icon = "far fa-list-alt",
|
||||
RuntimeDescription = "x => !!x.state.expression ? `Switch execution based on <strong>${ x.state.expression.expression }</strong>.` : x.definition.description",
|
||||
Outcomes = "x => x.state.cases.map(c => c.toString())"
|
||||
)]
|
||||
public class Switch : Activity
|
||||
|
|
@ -44,7 +41,8 @@ namespace Elsa.Activities.ControlFlow
|
|||
set => SetState(value);
|
||||
}
|
||||
|
||||
protected override async Task<ActivityExecutionResult> OnExecuteAsync(WorkflowExecutionContext workflowContext,
|
||||
protected override async Task<ActivityExecutionResult> OnExecuteAsync(
|
||||
WorkflowExecutionContext workflowContext,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
var result = await expressionEvaluator.EvaluateAsync(Expression, workflowContext, cancellationToken);
|
||||
|
|
|
|||
56
src/core/Elsa.Core/Activities/ControlFlow/While.cs
Normal file
56
src/core/Elsa.Core/Activities/ControlFlow/While.cs
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Elsa.Attributes;
|
||||
using Elsa.Expressions;
|
||||
using Elsa.Extensions;
|
||||
using Elsa.Results;
|
||||
using Elsa.Services;
|
||||
using Elsa.Services.Models;
|
||||
|
||||
namespace Elsa.Activities.ControlFlow
|
||||
{
|
||||
[ActivityDefinition(Category = "Control Flow", Description = "Execute while a given condition is true.", Icon = "far fa-circle")]
|
||||
public class While : Activity
|
||||
{
|
||||
private readonly IWorkflowExpressionEvaluator expressionEvaluator;
|
||||
|
||||
public While(IWorkflowExpressionEvaluator expressionEvaluator)
|
||||
{
|
||||
this.expressionEvaluator = expressionEvaluator;
|
||||
}
|
||||
|
||||
[ActivityProperty(Hint = "Enter an expression that evaluates to a boolean value.")]
|
||||
public WorkflowExpression<bool> ConditionExpression
|
||||
{
|
||||
get => GetState(() => new JavaScriptExpression<bool>("true"));
|
||||
set => SetState(value);
|
||||
}
|
||||
|
||||
public bool HasStarted
|
||||
{
|
||||
get => GetState(() => false);
|
||||
set => SetState(value);
|
||||
}
|
||||
|
||||
protected override async Task<ActivityExecutionResult> OnExecuteAsync(
|
||||
WorkflowExecutionContext context,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
var loop = await expressionEvaluator.EvaluateAsync(ConditionExpression, context, cancellationToken);
|
||||
|
||||
if(HasStarted)
|
||||
context.EndScope();
|
||||
|
||||
if (loop)
|
||||
{
|
||||
if (!HasStarted)
|
||||
HasStarted = true;
|
||||
|
||||
context.BeginScope();
|
||||
return Outcome(OutcomeNames.Loop);
|
||||
}
|
||||
|
||||
return Done();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -11,11 +11,8 @@ namespace Elsa.Activities.Primitives
|
|||
[ActivityDefinition(
|
||||
DisplayName = "Set Variable",
|
||||
Description = "Set variable on the workflow.",
|
||||
Category = "Primitives"
|
||||
)]
|
||||
[ActivityDefinitionDesigner(
|
||||
Description =
|
||||
"x => !!x.state.variableName ? `<strong>${x.state.variableName}</strong> = <strong>${x.state.valueExpression.expression}</strong><br/>${x.state.valueExpression.syntax}` : x.definition.description",
|
||||
Category = "Primitives",
|
||||
RuntimeDescription = "x => !!x.state.variableName ? `<strong>${x.state.variableName}</strong> = <strong>${x.state.valueExpression.expression}</strong><br/>${x.state.valueExpression.syntax}` : x.definition.description",
|
||||
Outcomes = new[] { OutcomeNames.Done }
|
||||
)]
|
||||
public class SetVariable : Activity
|
||||
|
|
@ -51,7 +48,7 @@ namespace Elsa.Activities.Primitives
|
|||
workflowContext,
|
||||
cancellationToken
|
||||
);
|
||||
workflowContext.CurrentScope.SetVariable(VariableName, value);
|
||||
workflowContext.SetVariable(VariableName, value);
|
||||
return Done();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,10 +16,11 @@
|
|||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="AutoMapper" Version="9.0.0" />
|
||||
<PackageReference Include="Humanizer.Core" Version="2.7.9" />
|
||||
<PackageReference Include="MediatR" Version="7.0.0" />
|
||||
<PackageReference Include="MediatR.Extensions.Microsoft.DependencyInjection" Version="7.0.0" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Hosting.Server.Abstractions" Version="2.2.0" />
|
||||
<PackageReference Include="Microsoft.CSharp" Version="4.5.0" />
|
||||
<PackageReference Include="Microsoft.CSharp" Version="4.6.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Caching.Abstractions" Version="3.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="3.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="3.0.0" />
|
||||
|
|
@ -29,7 +30,7 @@
|
|||
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="3.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="3.0.0" />
|
||||
<PackageReference Include="NodaTime.Serialization.JsonNet" Version="2.2.0" />
|
||||
<PackageReference Include="Elsa.Scrutor" Version="3.0.2.25" />
|
||||
<PackageReference Include="Elsa.Scrutor" Version="3.0.2.26" />
|
||||
|
||||
<PackageReference Include="YamlDotNet.NetStandard" Version="4.0.0" />
|
||||
</ItemGroup>
|
||||
|
|
|
|||
|
|
@ -175,6 +175,7 @@ namespace Microsoft.Extensions.DependencyInjection
|
|||
{
|
||||
return services
|
||||
.AddActivity<ForEach>()
|
||||
.AddActivity<While>()
|
||||
.AddActivity<Fork>()
|
||||
.AddActivity<Join>()
|
||||
.AddSingleton<IWorkflowEventHandler>(sp => sp.GetRequiredService<Join>())
|
||||
|
|
|
|||
|
|
@ -7,22 +7,20 @@ using Elsa.Attributes;
|
|||
using Elsa.Design;
|
||||
using Elsa.Expressions;
|
||||
using Elsa.Services.Models;
|
||||
using Elsa.WorkflowDesigner.Models;
|
||||
using Humanizer;
|
||||
|
||||
namespace Elsa.WorkflowDesigner
|
||||
namespace Elsa.Metadata
|
||||
{
|
||||
public static class ActivityDescriber
|
||||
{
|
||||
public static ActivityDefinitionModel Describe<T>() where T : IActivity
|
||||
public static ActivityDescriptor Describe<T>() where T : IActivity
|
||||
{
|
||||
return Describe(typeof(T));
|
||||
}
|
||||
|
||||
public static ActivityDefinitionModel Describe(Type activityType)
|
||||
|
||||
public static ActivityDescriptor Describe(Type activityType)
|
||||
{
|
||||
var activityDefinitionAttribute = activityType.GetCustomAttribute<ActivityDefinitionAttribute>();
|
||||
var activityDesignerAttribute = activityType.GetCustomAttribute<ActivityDefinitionDesignerAttribute>();
|
||||
var typeName = activityDefinitionAttribute?.Type ?? activityType.Name;
|
||||
|
||||
var displayName =
|
||||
|
|
@ -30,25 +28,22 @@ namespace Elsa.WorkflowDesigner
|
|||
activityType.Name.Humanize(LetterCasing.Title);
|
||||
|
||||
var description = activityDefinitionAttribute?.Description;
|
||||
var runtimeDescription = activityDefinitionAttribute?.RuntimeDescription;
|
||||
var category = activityDefinitionAttribute?.Category ?? "Miscellaneous";
|
||||
var icon = activityDefinitionAttribute?.Icon;
|
||||
var designerDescription = activityDesignerAttribute?.Description;
|
||||
var designerOutcomes = activityDesignerAttribute?.Outcomes ?? new[] { OutcomeNames.Done };
|
||||
var outcomes = activityDefinitionAttribute?.Outcomes ?? new[] { OutcomeNames.Done };
|
||||
var properties = DescribeProperties(activityType);
|
||||
|
||||
return new ActivityDefinitionModel
|
||||
return new ActivityDescriptor
|
||||
{
|
||||
Type = typeName.Pascalize(),
|
||||
DisplayName = displayName,
|
||||
Description = description,
|
||||
RuntimeDescription = runtimeDescription,
|
||||
Category = category,
|
||||
Icon = icon,
|
||||
Properties = properties.ToArray(),
|
||||
Designer = new ActivityDesignerSettings
|
||||
{
|
||||
Description = designerDescription,
|
||||
Outcomes = designerOutcomes
|
||||
}
|
||||
Outcomes = outcomes
|
||||
};
|
||||
}
|
||||
|
||||
|
|
@ -1,23 +1,24 @@
|
|||
namespace Elsa.WorkflowDesigner.Models
|
||||
namespace Elsa.Metadata
|
||||
{
|
||||
public class ActivityDefinitionModel
|
||||
public class ActivityDescriptor
|
||||
{
|
||||
public ActivityDefinitionModel()
|
||||
public ActivityDescriptor()
|
||||
{
|
||||
Type = "Activity";
|
||||
Properties = new ActivityPropertyDescriptor[0];
|
||||
Category = "Miscellaneous";
|
||||
DisplayName = "Activity";
|
||||
Properties = new ActivityPropertyDescriptor[0];
|
||||
Designer = new ActivityDesignerSettings();
|
||||
Outcomes = null;
|
||||
}
|
||||
|
||||
public string Type { get; set; }
|
||||
public string DisplayName { get; set; }
|
||||
public string? Description { get; set; }
|
||||
public string? RuntimeDescription { get; set; }
|
||||
public string Category { get; set; }
|
||||
public string? Icon { get; set; }
|
||||
public object? Outcomes { get; set; }
|
||||
public ActivityPropertyDescriptor[] Properties { get; set; }
|
||||
public ActivityDesignerSettings Designer { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
namespace Elsa.WorkflowDesigner.Models
|
||||
namespace Elsa.Metadata
|
||||
{
|
||||
public class ActivityPropertyDescriptor
|
||||
{
|
||||
|
|
@ -23,7 +23,7 @@ namespace Elsa.Scripting
|
|||
engine.SetValue("correlationId", (Func<object>) (() => context.Workflow.CorrelationId));
|
||||
engine.SetValue("currentCulture", (Func<object>) (() => CultureInfo.InvariantCulture));
|
||||
|
||||
var variables = workflowExecutionContext.Workflow.Scopes
|
||||
var variables = workflowExecutionContext.Workflow.Scopes.Reverse()
|
||||
.Select(x => x.Variables)
|
||||
.Aggregate(Variables.Empty, (x, y) => new Variables(x.Union(y)));
|
||||
|
||||
|
|
|
|||
|
|
@ -52,8 +52,7 @@ namespace Elsa.Services
|
|||
var id = idGenerator.Generate();
|
||||
var workflow = new Workflow(
|
||||
id,
|
||||
definition.DefinitionId,
|
||||
definition.Version,
|
||||
definition,
|
||||
clock.GetCurrentInstant(),
|
||||
activities,
|
||||
connections,
|
||||
|
|
|
|||
|
|
@ -18,6 +18,8 @@ namespace Elsa.WorkflowBuilders
|
|||
public WorkflowBuilder WorkflowBuilder { get; }
|
||||
public ActivityDefinition Activity { get; }
|
||||
public string Id { get; set; }
|
||||
public string Description { get; set; }
|
||||
public string DisplayName { get; set; }
|
||||
|
||||
public IActivityBuilder StartWith<T>(Action<T> setup = default, string id = default) where T : class, IActivity
|
||||
{
|
||||
|
|
@ -45,6 +47,18 @@ namespace Elsa.WorkflowBuilders
|
|||
Id = id;
|
||||
return this;
|
||||
}
|
||||
|
||||
public IActivityBuilder WithDisplayName(string displayName)
|
||||
{
|
||||
DisplayName = displayName;
|
||||
return this;
|
||||
}
|
||||
|
||||
public IActivityBuilder WithDescription(string description)
|
||||
{
|
||||
Description = description;
|
||||
return this;
|
||||
}
|
||||
|
||||
public IWorkflowBuilder Then(string activityId)
|
||||
{
|
||||
|
|
@ -56,9 +70,17 @@ namespace Elsa.WorkflowBuilders
|
|||
return WorkflowBuilder;
|
||||
}
|
||||
|
||||
public IActivityBuilder Then(IActivityBuilder targetActivity)
|
||||
{
|
||||
WorkflowBuilder.Connect(this, targetActivity);
|
||||
return this;
|
||||
}
|
||||
|
||||
public ActivityDefinition BuildActivity()
|
||||
{
|
||||
Activity.Id = Id;
|
||||
Activity.Description = Description;
|
||||
Activity.DisplayName = DisplayName;
|
||||
return Activity;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Elsa.Metadata;
|
||||
using Elsa.Models;
|
||||
using Elsa.Services;
|
||||
using Elsa.Services.Models;
|
||||
|
|
@ -79,10 +80,13 @@ namespace Elsa.WorkflowBuilders
|
|||
var activity = activityResolver.ResolveActivity(setupActivity);
|
||||
var activityBlueprint = ActivityDefinition.FromActivity(activity);
|
||||
var activityBuilder = new ActivityBuilder(this, activityBlueprint, id);
|
||||
var activityDescriptor = ActivityDescriber.Describe<T>();
|
||||
|
||||
if (id != null)
|
||||
activity.Id = id;
|
||||
|
||||
activityBuilder.DisplayName = activityDescriptor.DisplayName;
|
||||
activityBuilder.Description = activityDescriptor.Description;
|
||||
activityBuilders.Add(activityBuilder);
|
||||
return activityBuilder;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
using Elsa.Metadata;
|
||||
using Elsa.WorkflowDesigner.Models;
|
||||
|
||||
namespace Elsa.Dashboard.Areas.Elsa.ViewModels
|
||||
|
|
@ -11,7 +12,7 @@ namespace Elsa.Dashboard.Areas.Elsa.ViewModels
|
|||
public string Description { get; set; }
|
||||
public bool IsSingleton { get; set; }
|
||||
public bool IsDisabled { get; set; }
|
||||
public ActivityDefinitionModel[] ActivityDefinitions { get; set; }
|
||||
public ActivityDescriptor[] ActivityDefinitions { get; set; }
|
||||
public WorkflowModel WorkflowModel { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,6 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Elsa.Metadata;
|
||||
using Elsa.Models;
|
||||
using Elsa.WorkflowDesigner.Models;
|
||||
|
||||
|
|
@ -11,7 +12,7 @@ namespace Elsa.Dashboard.Areas.Elsa.ViewModels
|
|||
WorkflowInstance workflowInstance,
|
||||
WorkflowDefinitionVersion workflowDefinition,
|
||||
WorkflowModel workflowModel,
|
||||
IEnumerable<ActivityDefinitionModel> activityDefinitions,
|
||||
IEnumerable<ActivityDescriptor> activityDefinitions,
|
||||
string returnUrl)
|
||||
{
|
||||
WorkflowInstance = workflowInstance;
|
||||
|
|
@ -24,7 +25,7 @@ namespace Elsa.Dashboard.Areas.Elsa.ViewModels
|
|||
public WorkflowInstance WorkflowInstance { get; }
|
||||
public WorkflowDefinitionVersion WorkflowDefinition { get; }
|
||||
public WorkflowModel WorkflowModel { get; }
|
||||
public ActivityDefinitionModel[] ActivityDefinitions { get; }
|
||||
public ActivityDescriptor[] ActivityDefinitions { get; }
|
||||
public string ReturnUrl { get; }
|
||||
}
|
||||
}
|
||||
|
|
@ -32,8 +32,8 @@
|
|||
<!-- CSS Files -->
|
||||
<link href="~/_content/Elsa.Dashboard/assets/css/argon-dashboard.css?v=1.1.0" rel="stylesheet"/>
|
||||
<link href="~/_content/Elsa.Dashboard/assets/css/elsa.css?v=1.1.0" rel="stylesheet"/>
|
||||
<script type="module" src="https://unpkg.com/@@elsa-workflows/elsa-workflow-designer@0.0.60/dist/elsa-workflow-designer/elsa-workflow-designer.esm.js"></script>
|
||||
<script nomodule="" src="https://unpkg.com/@@elsa-workflows/elsa-workflow-designer@0.0.60/dist/elsa-workflow-designer/elsa-workflow-designer.js"></script>
|
||||
<script type="module" src="https://unpkg.com/@@elsa-workflows/elsa-workflow-designer@0.0.61/dist/elsa-workflow-designer/elsa-workflow-designer.esm.js"></script>
|
||||
<script nomodule="" src="https://unpkg.com/@@elsa-workflows/elsa-workflow-designer@0.0.61/dist/elsa-workflow-designer/elsa-workflow-designer.js"></script>
|
||||
@await RenderSectionAsync("HeadScripts", false)
|
||||
</head>
|
||||
|
||||
|
|
|
|||
|
|
@ -12,9 +12,6 @@
|
|||
</div>
|
||||
<div class="col-4 text-right">
|
||||
<a href="#!" class="btn btn-secondary" onclick="exportWorkflow()">Download</a>
|
||||
<a href="#!" class="btn btn-secondary" data-toggle="modal" data-target="#workflow-properties-modal">
|
||||
<i class="ni ni-settings-gear-65"></i>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
using System;
|
||||
using Elsa.Dashboard.Options;
|
||||
using Elsa.Metadata;
|
||||
using Elsa.Services.Models;
|
||||
using Elsa.WorkflowDesigner;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
|
|
|||
|
|
@ -1,25 +1,26 @@
|
|||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using Elsa.Metadata;
|
||||
using Elsa.WorkflowDesigner.Models;
|
||||
|
||||
namespace Elsa.Dashboard.Options
|
||||
{
|
||||
public class ActivityDefinitionList : IEnumerable<ActivityDefinitionModel>
|
||||
public class ActivityDefinitionList : IEnumerable<ActivityDescriptor>
|
||||
{
|
||||
public ActivityDefinitionList()
|
||||
{
|
||||
Items = new Dictionary<string, ActivityDefinitionModel>();
|
||||
Items = new Dictionary<string, ActivityDescriptor>();
|
||||
}
|
||||
|
||||
private IDictionary<string, ActivityDefinitionModel> Items { get; }
|
||||
private IDictionary<string, ActivityDescriptor> Items { get; }
|
||||
|
||||
public ActivityDefinitionList Add(ActivityDefinitionModel item)
|
||||
public ActivityDefinitionList Add(ActivityDescriptor item)
|
||||
{
|
||||
Items[item.Type] = item;
|
||||
return this;
|
||||
}
|
||||
|
||||
public IEnumerator<ActivityDefinitionModel> GetEnumerator() => Items.Values.GetEnumerator();
|
||||
public IEnumerator<ActivityDescriptor> GetEnumerator() => Items.Values.GetEnumerator();
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -15,12 +15,12 @@
|
|||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Humanizer.Core" Version="2.7.2" />
|
||||
<PackageReference Include="Humanizer.Core" Version="2.7.9" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Mvc" Version="2.2.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\core\Elsa.Abstractions\Elsa.Abstractions.csproj" />
|
||||
<ProjectReference Include="..\..\core\Elsa.Core\Elsa.Core.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
|
|||
|
|
@ -1,8 +0,0 @@
|
|||
namespace Elsa.WorkflowDesigner.Models
|
||||
{
|
||||
public class ActivityDesignerSettings
|
||||
{
|
||||
public object? Description { get; set; }
|
||||
public object? Outcomes { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
@ -1,3 +1,4 @@
|
|||
using Elsa.Metadata;
|
||||
using Elsa.WorkflowDesigner.Models;
|
||||
using Elsa.WorkflowDesigner.ViewModels;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
|
@ -10,13 +11,13 @@ namespace Elsa.WorkflowDesigner.ViewComponents
|
|||
{
|
||||
public IViewComponentResult Invoke(
|
||||
string id,
|
||||
ActivityDefinitionModel[]? activityDefinitions = null,
|
||||
ActivityDescriptor[]? activityDefinitions = null,
|
||||
WorkflowModel? workflow = null,
|
||||
bool? isReadonly = null)
|
||||
{
|
||||
var model = new WorkflowDesignerViewComponentModel(
|
||||
id,
|
||||
Serialize(activityDefinitions ?? new ActivityDefinitionModel[0]),
|
||||
Serialize(activityDefinitions ?? new ActivityDescriptor[0]),
|
||||
Serialize(workflow ?? new WorkflowModel()),
|
||||
isReadonly.GetValueOrDefault()
|
||||
);
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Azure.DocumentDB.Core" Version="2.6.0" />
|
||||
<PackageReference Include="Microsoft.Azure.DocumentDB.Core" Version="2.8.1" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netstandard2.0</TargetFramework>
|
||||
<TargetFramework>netcoreapp2.2</TargetFramework>
|
||||
<TargetFramework>netcoreapp3.0</TargetFramework>
|
||||
<LangVersion>latest</LangVersion>
|
||||
<PackageVersion>1.0.0</PackageVersion>
|
||||
<Authors>Sipke Schoorstra</Authors>
|
||||
|
|
@ -15,11 +15,11 @@
|
|||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="FlexLabs.EntityFrameworkCore.Upsert" Version="2.2.0" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="2.2.6" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="2.2.6" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="2.2.6" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="2.2.6" />
|
||||
<PackageReference Include="FlexLabs.EntityFrameworkCore.Upsert" Version="3.0.0" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="3.0.0" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="3.0.0" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="3.0.0" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="3.0.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
|
|
|||
|
|
@ -21,11 +21,11 @@
|
|||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="3.0.0" />
|
||||
<PackageReference Include="YesSql.Core" Version="2.0.0-beta-1395" />
|
||||
<PackageReference Include="YesSql.Provider.MySql" Version="1.0.0-beta-1395" />
|
||||
<PackageReference Include="YesSql.Provider.PostgreSql" Version="1.0.0-beta-1395" />
|
||||
<PackageReference Include="YesSql.Provider.Sqlite" Version="1.0.0-beta-1395" />
|
||||
<PackageReference Include="YesSql.Provider.SqlServer" Version="1.0.0-beta-1395" />
|
||||
<PackageReference Include="YesSql.Core" Version="2.0.0-beta-1437" />
|
||||
<PackageReference Include="YesSql.Provider.MySql" Version="1.0.0-beta-1437" />
|
||||
<PackageReference Include="YesSql.Provider.PostgreSql" Version="1.0.0-beta-1437" />
|
||||
<PackageReference Include="YesSql.Provider.Sqlite" Version="1.0.0-beta-1437" />
|
||||
<PackageReference Include="YesSql.Provider.SqlServer" Version="1.0.0-beta-1437" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>netcoreapp2.2</TargetFramework>
|
||||
<TargetFramework>netcoreapp3.0</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>netcoreapp2.2</TargetFramework>
|
||||
<TargetFramework>netcoreapp3.0</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>netcoreapp2.2</TargetFramework>
|
||||
<TargetFramework>netcoreapp3.0</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
using Elsa;
|
||||
using Elsa.Activities.Console.Activities;
|
||||
using Elsa.Activities.ControlFlow;
|
||||
using Elsa.Activities.Primitives;
|
||||
using Elsa.Expressions;
|
||||
using Elsa.Services;
|
||||
using Elsa.Services.Models;
|
||||
|
|
@ -13,57 +14,66 @@ namespace Sample04
|
|||
public void Build(IWorkflowBuilder builder)
|
||||
{
|
||||
builder
|
||||
.StartWith<WriteLine>(x => x.TextExpression = new LiteralExpression("Welcome to Calculator Workflow!"), "welcome")
|
||||
.Then<WriteLine>(x => x.TextExpression = new LiteralExpression("Enter number 1:"), id: "enter-first-number-prompt")
|
||||
.Then<ReadLine>(x => x.VariableName = "number1", id: "read-first-number")
|
||||
.Then<WriteLine>(x => x.TextExpression = new LiteralExpression("Enter number 2:"), id: "enter-second-number-prompt")
|
||||
.Then<ReadLine>(x => x.VariableName = "number2", id: "read-second-number")
|
||||
.Then<WriteLine>(x => x.TextExpression = new LiteralExpression("Now enter the operation you wish to apply. Options are: add, subtract, multiply or divide:"), id: "enter-operation-prompt")
|
||||
.Then<ReadLine>(x => x.VariableName = "operation", id: "read-operation")
|
||||
.Then<Switch>(@switch =>
|
||||
.StartWith<WriteLine>(x => x.TextExpression = new LiteralExpression("Welcome to Calculator Workflow!")).WithDisplayName("Welcome")
|
||||
.Then<SetVariable>(
|
||||
x =>
|
||||
{
|
||||
@switch.Expression = new JavaScriptExpression<string>("operation");
|
||||
@switch.Cases = new[] { "add", "subtract", "multiply", "divide" };
|
||||
},
|
||||
@switch =>
|
||||
x.VariableName = "Exit";
|
||||
x.ValueExpression = new JavaScriptExpression<bool>("false");
|
||||
}).WithDisplayName("Initialize Exit Variable")
|
||||
.Then<While>(
|
||||
x => x.ConditionExpression = new JavaScriptExpression<bool>("!Exit"),
|
||||
whileActivity =>
|
||||
{
|
||||
@switch
|
||||
.When("add")
|
||||
.Then<Sum>(SetupOperation, id: "perform-sum")
|
||||
.Then("show-result");
|
||||
|
||||
@switch
|
||||
.When("subtract")
|
||||
.Then<Subtract>(SetupOperation, id: "perform-subtract")
|
||||
.Then("show-result");
|
||||
|
||||
@switch
|
||||
.When("multiply")
|
||||
.Then<Multiply>(SetupOperation, id: "perform-multiply")
|
||||
.Then("show-result");
|
||||
|
||||
@switch
|
||||
.When("divide")
|
||||
.Then<Divide>(SetupOperation, id: "perform-divide")
|
||||
.Then("show-result");
|
||||
},
|
||||
"inspect-selected-operation"
|
||||
)
|
||||
.Add<WriteLine>(x => x.TextExpression = new JavaScriptExpression<string>("`Result: ${result}`"), "show-result")
|
||||
.Then<WriteLine>(x => x.TextExpression = new LiteralExpression("Try again? (y/n)"), id: "try-again-prompt")
|
||||
.Then<ReadLine>(x => x.VariableName = "retry", id: "read-try-again")
|
||||
.Then<IfElse>(
|
||||
x => x.ConditionExpression = new JavaScriptExpression<bool>("retry.toLowerCase() === 'y'"),
|
||||
ifElse =>
|
||||
{
|
||||
ifElse
|
||||
.When(OutcomeNames.True)
|
||||
.Then("enter-first-number-prompt");
|
||||
|
||||
ifElse
|
||||
.When(OutcomeNames.False)
|
||||
.Then<WriteLine>(x => x.TextExpression = new LiteralExpression("Bye!"), id: "say-good-bye");
|
||||
}, id: "inspect-retry");
|
||||
whileActivity
|
||||
.When(OutcomeNames.Loop)
|
||||
.Then<WriteLine>(x => x.TextExpression = new LiteralExpression("Enter number 1:"))
|
||||
.Then<ReadLine>(x => x.VariableName = "number1")
|
||||
.Then<WriteLine>(x => x.TextExpression = new LiteralExpression("Enter number 2:"))
|
||||
.Then<ReadLine>(x => x.VariableName = "number2")
|
||||
.Then<WriteLine>(x => x.TextExpression = new LiteralExpression("Now enter the operation you wish to apply. Options are: add, subtract, multiply or divide:"))
|
||||
.Then<ReadLine>(x => x.VariableName = "operation")
|
||||
.Then<Switch>(
|
||||
@switch =>
|
||||
{
|
||||
@switch.Expression = new JavaScriptExpression<string>("operation");
|
||||
@switch.Cases = new[] { "add", "subtract", "multiply", "divide" };
|
||||
},
|
||||
@switch =>
|
||||
{
|
||||
@switch
|
||||
.When("add")
|
||||
.Then<Sum>(SetupOperation, id: "perform-sum")
|
||||
.Then("ShowResult");
|
||||
|
||||
@switch
|
||||
.When("subtract")
|
||||
.Then<Subtract>(SetupOperation, id: "perform-subtract")
|
||||
.Then("ShowResult");
|
||||
|
||||
@switch
|
||||
.When("multiply")
|
||||
.Then<Multiply>(SetupOperation, id: "perform-multiply")
|
||||
.Then("ShowResult");
|
||||
|
||||
@switch
|
||||
.When("divide")
|
||||
.Then<Divide>(SetupOperation, id: "perform-divide")
|
||||
.Then("ShowResult");
|
||||
},
|
||||
"inspect-selected-operation"
|
||||
)
|
||||
.Add<WriteLine>(x => x.TextExpression = new JavaScriptExpression<string>("`Result: ${result}`")).WithId("ShowResult")
|
||||
.Then<WriteLine>(x => x.TextExpression = new LiteralExpression("Try again? (y/n)"))
|
||||
.Then<ReadLine>().WithId("TryAgain")
|
||||
.Then<SetVariable>(x =>
|
||||
{
|
||||
x.VariableName = "Exit";
|
||||
x.ValueExpression = new JavaScriptExpression<bool>("TryAgain.Input !== 'y' && TryAgain.Input !== 'Y'");
|
||||
})
|
||||
.Then(whileActivity);
|
||||
}).WithDisplayName("While")
|
||||
.Then<WriteLine>(x => x.TextExpression = new LiteralExpression("Bye!"));
|
||||
}
|
||||
|
||||
private void SetupOperation(ArithmeticOperation operation)
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
using System;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Elsa.Activities.Console.Extensions;
|
||||
using Elsa.Services;
|
||||
|
|
@ -16,6 +17,7 @@ namespace Sample04
|
|||
{
|
||||
// Setup a service collection.
|
||||
var services = new ServiceCollection()
|
||||
.AddSingleton(Console.In)
|
||||
.AddWorkflows()
|
||||
.AddConsoleActivities()
|
||||
.AddActivity<Sum>()
|
||||
|
|
@ -35,7 +37,8 @@ namespace Sample04
|
|||
Console.WriteLine("Workflow has ended. Here are the activities that have executed:");
|
||||
foreach (var logEntry in workflow.ExecutionLog)
|
||||
{
|
||||
Console.WriteLine("{0}: {1}", logEntry.Timestamp, logEntry.ActivityId);
|
||||
var activity = workflow.Definition.Activities.First(x => x.Id == logEntry.ActivityId);
|
||||
Console.WriteLine("{0}: {1}", logEntry.Timestamp, activity.DisplayName);
|
||||
}
|
||||
Console.ReadLine();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@
|
|||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Extensions.Hosting" Version="3.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Hosting" Version="3.1.0-preview1.19506.1" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="MassTransit.AspNetCore" Version="5.5.2" />
|
||||
<PackageReference Include="MassTransit.AspNetCore" Version="6.0.0-develop.2231" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>netcoreapp2.2</TargetFramework>
|
||||
<TargetFramework>netcoreapp3.0</TargetFramework>
|
||||
<LangVersion>latest</LangVersion>
|
||||
</PropertyGroup>
|
||||
|
||||
|
|
@ -16,8 +16,8 @@
|
|||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="2.2.6" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="2.2.6" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="3.0.0" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="3.0.0" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
|
|||
Loading…
Reference in a new issue