Add FlowDecision activity

This commit is contained in:
Sipke Schoorstra 2022-07-07 21:39:54 +02:00
parent 845cd52902
commit fb2a4cc041
2 changed files with 80 additions and 1 deletions

View file

@ -7,7 +7,7 @@ using Elsa.Workflows.Core.Models;
namespace Elsa.Workflows.Core.Activities.Flowchart.Activities;
[FlowNode("True", "False")]
[Activity("Elsa", "Flow", "Continues on either the True or False branch, depending on the result of a specified condition")]
[Activity("Elsa", "Flow", "Evaluate a Boolean condition to determine which path to execute next.")]
public class FlowDecision : ActivityBase
{
/// <summary>

View file

@ -0,0 +1,79 @@
using System.Text.Json.Serialization;
using Elsa.Expressions;
using Elsa.Expressions.Models;
using Elsa.Expressions.Services;
using Elsa.Workflows.Core.Activities.Flowchart.Attributes;
using Elsa.Workflows.Core.Attributes;
using Elsa.Workflows.Core.Models;
namespace Elsa.Workflows.Core.Activities.Flowchart.Activities;
[FlowNode("Default")]
[Activity("Elsa", "Flow", "Evaluate a set of case conditions and schedule the activity for a matching case.")]
public class FlowSwitch : ActivityBase
{
[Input(UIHint = "flow-switch-editor")] public ICollection<FlowSwitchCase> Cases { get; set; } = new List<FlowSwitchCase>();
protected override async ValueTask ExecuteAsync(ActivityExecutionContext context)
{
var matchingCase = await FindMatchingCaseAsync(context.ExpressionExecutionContext);
var outcome = matchingCase?.Label ?? "Default";
await context.CompleteActivityAsync(outcome);
}
private async Task<FlowSwitchCase?> FindMatchingCaseAsync(ExpressionExecutionContext context)
{
var expressionEvaluator = context.GetRequiredService<IExpressionEvaluator>();
foreach (var switchCase in Cases)
{
var result = await expressionEvaluator.EvaluateAsync<bool?>(switchCase.Condition, context);
if (result == true)
return switchCase;
}
return null;
}
}
/// <summary>
/// Represents an individual case of the <see cref="FlowSwitch"/> activity.
/// </summary>
public class FlowSwitchCase
{
[JsonConstructor]
public FlowSwitchCase()
{
}
public FlowSwitchCase(string label, IExpression condition)
{
Label = label;
Condition = condition;
}
public FlowSwitchCase(string label, DelegateBlockReference<bool> condition) : this(label, new DelegateExpression(condition))
{
}
public FlowSwitchCase(string label, Func<ExpressionExecutionContext, ValueTask<bool>> condition) : this(label, new DelegateBlockReference<bool>(condition))
{
}
public FlowSwitchCase(string label, Func<ValueTask<bool>> condition) : this(label, new DelegateBlockReference<bool>(condition))
{
}
public FlowSwitchCase(string label, Func<ExpressionExecutionContext, bool> condition) : this(label, new DelegateBlockReference<bool>(condition))
{
}
public FlowSwitchCase(string label, Func<bool> condition) : this(label, new DelegateBlockReference<bool>(condition))
{
}
public string Label { get; set; } = default!;
public IExpression Condition { get; set; } = new LiteralExpression(false);
}