Implement activity picker filtering
This commit is contained in:
parent
f652f1717a
commit
6bddf50d77
|
|
@ -9,6 +9,7 @@ indent_size=4
|
||||||
# ReSharper properties
|
# ReSharper properties
|
||||||
resharper_csharp_max_line_length=240
|
resharper_csharp_max_line_length=240
|
||||||
resharper_keep_user_linebreaks=true
|
resharper_keep_user_linebreaks=true
|
||||||
|
resharper_space_within_single_line_array_initializer_braces=true
|
||||||
|
|
||||||
# Microsoft .NET properties
|
# Microsoft .NET properties
|
||||||
csharp_new_line_before_members_in_object_initializers=false
|
csharp_new_line_before_members_in_object_initializers=false
|
||||||
|
|
|
||||||
|
|
@ -12,10 +12,9 @@ namespace Elsa.Activities.Console
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Reads input from the console.
|
/// Reads input from the console.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[ActivityDefinition(
|
[Action(
|
||||||
Category = "Console",
|
Category = "Console",
|
||||||
Description = "Read text from standard in.",
|
Description = "Read text from standard in.",
|
||||||
Icon = "fas fa-terminal",
|
|
||||||
Outcomes = new[] { OutcomeNames.Done }
|
Outcomes = new[] { OutcomeNames.Done }
|
||||||
)]
|
)]
|
||||||
public class ReadLine : Activity
|
public class ReadLine : Activity
|
||||||
|
|
@ -44,7 +43,7 @@ namespace Elsa.Activities.Console
|
||||||
|
|
||||||
protected override IActivityExecutionResult OnResume(ActivityExecutionContext context)
|
protected override IActivityExecutionResult OnResume(ActivityExecutionContext context)
|
||||||
{
|
{
|
||||||
var receivedInput = (string)context.Input!;
|
var receivedInput = (string) context.Input!;
|
||||||
return Execute(receivedInput);
|
return Execute(receivedInput);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -12,10 +12,9 @@ namespace Elsa.Activities.Console
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Writes a text string to the console.
|
/// Writes a text string to the console.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[ActivityDefinition(
|
[Action(
|
||||||
Category = "Console",
|
Category = "Console",
|
||||||
Description = "Write text to standard out.",
|
Description = "Write text to standard out.",
|
||||||
Icon = "fas fa-terminal",
|
|
||||||
Outcomes = new[] { OutcomeNames.Done }
|
Outcomes = new[] { OutcomeNames.Done }
|
||||||
)]
|
)]
|
||||||
public class WriteLine : Activity
|
public class WriteLine : Activity
|
||||||
|
|
|
||||||
|
|
@ -9,10 +9,11 @@ using Elsa.Services.Models;
|
||||||
|
|
||||||
namespace Elsa.Activities.Dropbox.Activities
|
namespace Elsa.Activities.Dropbox.Activities
|
||||||
{
|
{
|
||||||
[ActivityDefinition(
|
[Action(
|
||||||
Category = "Dropbox",
|
Category = "Dropbox",
|
||||||
Description = "Saves a given file or byte array to a folder in Dropbox",
|
Description = "Saves a given file or byte array to a folder in Dropbox",
|
||||||
Icon = "fab fa-dropbox")]
|
Outcomes = new[] { OutcomeNames.Done }
|
||||||
|
)]
|
||||||
public class SaveToDropbox : Activity
|
public class SaveToDropbox : Activity
|
||||||
{
|
{
|
||||||
private readonly IFilesApi _filesApi;
|
private readonly IFilesApi _filesApi;
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ using MimeKit.Text;
|
||||||
// ReSharper disable once CheckNamespace
|
// ReSharper disable once CheckNamespace
|
||||||
namespace Elsa.Activities.Email
|
namespace Elsa.Activities.Email
|
||||||
{
|
{
|
||||||
[ActivityDefinition(Category = "Email", Description = "Send an email message.")]
|
[Action(Category = "Email", Description = "Send an email message.")]
|
||||||
public class SendEmail : Activity
|
public class SendEmail : Activity
|
||||||
{
|
{
|
||||||
private readonly ISmtpService _smtpService;
|
private readonly ISmtpService _smtpService;
|
||||||
|
|
|
||||||
|
|
@ -15,11 +15,10 @@ using Microsoft.AspNetCore.Http;
|
||||||
// ReSharper disable once CheckNamespace
|
// ReSharper disable once CheckNamespace
|
||||||
namespace Elsa.Activities.Http
|
namespace Elsa.Activities.Http
|
||||||
{
|
{
|
||||||
[ActivityDefinition(
|
[Trigger(
|
||||||
Category = "HTTP",
|
Category = "HTTP",
|
||||||
DisplayName = "Receive HTTP Request",
|
DisplayName = "Receive HTTP Request",
|
||||||
Description = "Receive an incoming HTTP request.",
|
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 }
|
Outcomes = new[] { OutcomeNames.Done }
|
||||||
)]
|
)]
|
||||||
public class ReceiveHttpRequest : Activity
|
public class ReceiveHttpRequest : Activity
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ using Microsoft.Extensions.Localization;
|
||||||
// ReSharper disable once CheckNamespace
|
// ReSharper disable once CheckNamespace
|
||||||
namespace Elsa.Activities.Http
|
namespace Elsa.Activities.Http
|
||||||
{
|
{
|
||||||
[ActivityDefinition(
|
[Action(
|
||||||
Category = "HTTP",
|
Category = "HTTP",
|
||||||
DisplayName = "Redirect",
|
DisplayName = "Redirect",
|
||||||
Description = "Write an HTTP redirect response.",
|
Description = "Write an HTTP redirect response.",
|
||||||
|
|
|
||||||
|
|
@ -19,15 +19,11 @@ using HttpRequestHeaders = Elsa.Activities.Http.Models.HttpRequestHeaders;
|
||||||
// ReSharper disable once CheckNamespace
|
// ReSharper disable once CheckNamespace
|
||||||
namespace Elsa.Activities.Http
|
namespace Elsa.Activities.Http
|
||||||
{
|
{
|
||||||
[ActivityDefinition(
|
[Action(
|
||||||
Category = "HTTP",
|
Category = "HTTP",
|
||||||
DisplayName = "Send HTTP Request",
|
DisplayName = "Send HTTP Request",
|
||||||
Description = "Send an HTTP request.",
|
Description = "Send an HTTP request.",
|
||||||
Outcomes = new[]
|
Outcomes = new[] { OutcomeNames.Done }
|
||||||
{
|
|
||||||
OutcomeNames.Done,
|
|
||||||
"x => !!x.state.supportedStatusCodes ? ['UnSupportedStatusCode', ...x.state.supportedStatusCodes] : ['UnSupportedStatusCode']"
|
|
||||||
}
|
|
||||||
)]
|
)]
|
||||||
public class SendHttpRequest : Activity
|
public class SendHttpRequest : Activity
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ using Microsoft.Extensions.Localization;
|
||||||
// ReSharper disable once CheckNamespace
|
// ReSharper disable once CheckNamespace
|
||||||
namespace Elsa.Activities.Http
|
namespace Elsa.Activities.Http
|
||||||
{
|
{
|
||||||
[ActivityDefinition(
|
[Action(
|
||||||
Category = "HTTP",
|
Category = "HTTP",
|
||||||
DisplayName = "Write HTTP Response",
|
DisplayName = "Write HTTP Response",
|
||||||
Description = "Write an HTTP response.",
|
Description = "Write an HTTP response.",
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ using Microsoft.Extensions.Options;
|
||||||
// ReSharper disable once CheckNamespace
|
// ReSharper disable once CheckNamespace
|
||||||
namespace Elsa.Activities.MassTransit
|
namespace Elsa.Activities.MassTransit
|
||||||
{
|
{
|
||||||
[ActivityDefinition(
|
[Action(
|
||||||
Category = "MassTransit",
|
Category = "MassTransit",
|
||||||
DisplayName = "Cancel scheduled MassTransit Message",
|
DisplayName = "Cancel scheduled MassTransit Message",
|
||||||
Description = "Cancel a scheduled message via MassTransit."
|
Description = "Cancel a scheduled message via MassTransit."
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ using MassTransit;
|
||||||
// ReSharper disable once CheckNamespace
|
// ReSharper disable once CheckNamespace
|
||||||
namespace Elsa.Activities.MassTransit
|
namespace Elsa.Activities.MassTransit
|
||||||
{
|
{
|
||||||
[ActivityDefinition(
|
[Action(
|
||||||
Category = "MassTransit",
|
Category = "MassTransit",
|
||||||
DisplayName = "Publish MassTransit Message",
|
DisplayName = "Publish MassTransit Message",
|
||||||
Description = "Publish an event via MassTransit."
|
Description = "Publish an event via MassTransit."
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ using Elsa.Services.Models;
|
||||||
// ReSharper disable once CheckNamespace
|
// ReSharper disable once CheckNamespace
|
||||||
namespace Elsa.Activities.MassTransit
|
namespace Elsa.Activities.MassTransit
|
||||||
{
|
{
|
||||||
[ActivityDefinition(
|
[Trigger(
|
||||||
Category = "MassTransit",
|
Category = "MassTransit",
|
||||||
DisplayName = "Receive MassTransit Message",
|
DisplayName = "Receive MassTransit Message",
|
||||||
Description = "Receive a message via MassTransit."
|
Description = "Receive a message via MassTransit."
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ using NodaTime;
|
||||||
// ReSharper disable once CheckNamespace
|
// ReSharper disable once CheckNamespace
|
||||||
namespace Elsa.Activities.MassTransit
|
namespace Elsa.Activities.MassTransit
|
||||||
{
|
{
|
||||||
[ActivityDefinition(
|
[Action(
|
||||||
Category = "MassTransit",
|
Category = "MassTransit",
|
||||||
DisplayName = "Schedule MassTransit Message",
|
DisplayName = "Schedule MassTransit Message",
|
||||||
Description = "Schedule a message via MassTransit."
|
Description = "Schedule a message via MassTransit."
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ using MassTransit;
|
||||||
// ReSharper disable once CheckNamespace
|
// ReSharper disable once CheckNamespace
|
||||||
namespace Elsa.Activities.MassTransit
|
namespace Elsa.Activities.MassTransit
|
||||||
{
|
{
|
||||||
[ActivityDefinition(
|
[Action(
|
||||||
Category = "MassTransit",
|
Category = "MassTransit",
|
||||||
DisplayName = "Send MassTransit Message",
|
DisplayName = "Send MassTransit Message",
|
||||||
Description = "Send a message via MassTransit."
|
Description = "Send a message via MassTransit."
|
||||||
|
|
|
||||||
|
|
@ -6,18 +6,17 @@ using Elsa.Services.Models;
|
||||||
// ReSharper disable once CheckNamespace
|
// ReSharper disable once CheckNamespace
|
||||||
namespace Elsa.Activities.Timers
|
namespace Elsa.Activities.Timers
|
||||||
{
|
{
|
||||||
[ActivityDefinition(
|
[Trigger(
|
||||||
Category = "Timers",
|
Category = "Timers",
|
||||||
Description = "Triggers periodically based on a specified CRON expression.",
|
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 }
|
Outcomes = new[] { OutcomeNames.Done }
|
||||||
)]
|
)]
|
||||||
public class CronEvent : Activity
|
public class CronEvent : Activity
|
||||||
{
|
{
|
||||||
[ActivityProperty(Hint = "Specify a CRON expression. See https://crontab.guru/ for help.")]
|
[ActivityProperty(Hint = "Specify a CRON expression. See https://crontab.guru/ for help.")]
|
||||||
public string CronExpression { get; set; } = "* * * * *";
|
public string CronExpression { get; set; } = "* * * * *";
|
||||||
|
|
||||||
protected override IActivityExecutionResult OnExecute(ActivityExecutionContext context) => context.WorkflowExecutionContext.IsFirstPass ? (IActivityExecutionResult)Done() : Suspend();
|
protected override IActivityExecutionResult OnExecute(ActivityExecutionContext context) => context.WorkflowExecutionContext.IsFirstPass ? (IActivityExecutionResult) Done() : Suspend();
|
||||||
protected override IActivityExecutionResult OnResume() => Done();
|
protected override IActivityExecutionResult OnResume() => Done();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -10,7 +10,7 @@ namespace Elsa.Activities.Timers
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Triggers at a specific instant in the future.
|
/// Triggers at a specific instant in the future.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[ActivityDefinition(
|
[Trigger(
|
||||||
Category = "Timers",
|
Category = "Timers",
|
||||||
Description = "Triggers at a specified moment in time."
|
Description = "Triggers at a specified moment in time."
|
||||||
)]
|
)]
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ using NodaTime;
|
||||||
// ReSharper disable once CheckNamespace
|
// ReSharper disable once CheckNamespace
|
||||||
namespace Elsa.Activities.Timers
|
namespace Elsa.Activities.Timers
|
||||||
{
|
{
|
||||||
[ActivityDefinition(Category = "Timers", Description = "Triggers at a specified interval.")]
|
[Trigger(Category = "Timers", Description = "Triggers at a specified interval.")]
|
||||||
public class TimerEvent : Activity
|
public class TimerEvent : Activity
|
||||||
{
|
{
|
||||||
[ActivityProperty(Hint = "An expression that evaluates to a Duration value.")]
|
[ActivityProperty(Hint = "An expression that evaluates to a Duration value.")]
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ namespace Elsa.Activities.UserTask.Activities
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Stores a set of possible user actions and halts the workflow until one of the actions has been performed.
|
/// Stores a set of possible user actions and halts the workflow until one of the actions has been performed.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[ActivityDefinition(
|
[Trigger(
|
||||||
Category = "User Tasks",
|
Category = "User Tasks",
|
||||||
Description = "Triggers when a user action is received.",
|
Description = "Triggers when a user action is received.",
|
||||||
Outcomes = new[] { OutcomeNames.Done, "x => x.state.actions" }
|
Outcomes = new[] { OutcomeNames.Done, "x => x.state.actions" }
|
||||||
|
|
|
||||||
|
|
@ -8,10 +8,9 @@ namespace Elsa.Client.Models
|
||||||
[DataMember(Order = 1)] public string Type { get; set; } = default!;
|
[DataMember(Order = 1)] public string Type { get; set; } = default!;
|
||||||
[DataMember(Order = 2)] public string DisplayName { get; set; } = default!;
|
[DataMember(Order = 2)] public string DisplayName { get; set; } = default!;
|
||||||
[DataMember(Order = 3)] public string? Description { get; set; }
|
[DataMember(Order = 3)] public string? Description { get; set; }
|
||||||
[DataMember(Order = 4)] public string? RuntimeDescription { get; set; }
|
[DataMember(Order = 4)] public string Category { get; set; } = default!;
|
||||||
[DataMember(Order = 5)] public string Category { get; set; } = default!;
|
[DataMember(Order = 5)] public ActivityTraits Traits { get; set; }
|
||||||
[DataMember(Order = 6)] public string? Icon { get; set; }
|
[DataMember(Order = 6)] public string[] Outcomes { get; set; } = new string[0];
|
||||||
[DataMember(Order = 7)] public string[] Outcomes { get; set; } = new string[0];
|
[DataMember(Order = 7)] public ActivityPropertyDescriptor[] Properties { get; set; } = new ActivityPropertyDescriptor[0];
|
||||||
[DataMember(Order = 8)] public ActivityPropertyDescriptor[] Properties { get; set; } = new ActivityPropertyDescriptor[0];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
12
src/clients/Elsa.Client/Models/ActivityTraits.cs
Normal file
12
src/clients/Elsa.Client/Models/ActivityTraits.cs
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Elsa.Client.Models
|
||||||
|
{
|
||||||
|
[Flags]
|
||||||
|
public enum ActivityTraits
|
||||||
|
{
|
||||||
|
Action = 1,
|
||||||
|
Trigger = 2,
|
||||||
|
Job = 4
|
||||||
|
}
|
||||||
|
}
|
||||||
14
src/core/Elsa.Abstractions/Attributes/ActionAttribute.cs
Normal file
14
src/core/Elsa.Abstractions/Attributes/ActionAttribute.cs
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
using System;
|
||||||
|
using Elsa.Metadata;
|
||||||
|
|
||||||
|
namespace Elsa.Attributes
|
||||||
|
{
|
||||||
|
[AttributeUsage(AttributeTargets.Class)]
|
||||||
|
public sealed class ActionAttribute : ActivityAttribute
|
||||||
|
{
|
||||||
|
public ActionAttribute()
|
||||||
|
{
|
||||||
|
Traits = ActivityTraits.Action;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,16 +1,16 @@
|
||||||
using System;
|
using System;
|
||||||
|
using Elsa.Metadata;
|
||||||
|
|
||||||
namespace Elsa.Attributes
|
namespace Elsa.Attributes
|
||||||
{
|
{
|
||||||
[AttributeUsage(AttributeTargets.Class)]
|
[AttributeUsage(AttributeTargets.Class)]
|
||||||
public class ActivityDefinitionAttribute : Attribute
|
public class ActivityAttribute : Attribute
|
||||||
{
|
{
|
||||||
public string? Type { get; set; }
|
public string? Type { get; set; }
|
||||||
public string? DisplayName { get; set; }
|
public string? DisplayName { get; set; }
|
||||||
public string? Description { get; set; }
|
public string? Description { get; set; }
|
||||||
public string? RuntimeDescription { get; set; }
|
|
||||||
public string? Category { get; set; }
|
public string? Category { get; set; }
|
||||||
public string? Icon { get; set; }
|
public ActivityTraits Traits { get; set; } = ActivityTraits.Action;
|
||||||
public string[]? Outcomes { get; set; }
|
public string[]? Outcomes { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
14
src/core/Elsa.Abstractions/Attributes/TriggerAttribute.cs
Normal file
14
src/core/Elsa.Abstractions/Attributes/TriggerAttribute.cs
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
using System;
|
||||||
|
using Elsa.Metadata;
|
||||||
|
|
||||||
|
namespace Elsa.Attributes
|
||||||
|
{
|
||||||
|
[AttributeUsage(AttributeTargets.Class)]
|
||||||
|
public sealed class TriggerAttribute : ActivityAttribute
|
||||||
|
{
|
||||||
|
public TriggerAttribute()
|
||||||
|
{
|
||||||
|
Traits = ActivityTraits.Trigger;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -7,6 +7,7 @@ namespace Elsa.Metadata
|
||||||
Type = "Activity";
|
Type = "Activity";
|
||||||
Properties = new ActivityPropertyDescriptor[0];
|
Properties = new ActivityPropertyDescriptor[0];
|
||||||
Category = "Miscellaneous";
|
Category = "Miscellaneous";
|
||||||
|
Traits = ActivityTraits.Action;
|
||||||
DisplayName = "Activity";
|
DisplayName = "Activity";
|
||||||
Properties = new ActivityPropertyDescriptor[0];
|
Properties = new ActivityPropertyDescriptor[0];
|
||||||
Outcomes = new string[0];
|
Outcomes = new string[0];
|
||||||
|
|
@ -15,9 +16,8 @@ namespace Elsa.Metadata
|
||||||
public string Type { get; set; }
|
public string Type { get; set; }
|
||||||
public string DisplayName { get; set; }
|
public string DisplayName { get; set; }
|
||||||
public string? Description { get; set; }
|
public string? Description { get; set; }
|
||||||
public string? RuntimeDescription { get; set; }
|
|
||||||
public string Category { get; set; }
|
public string Category { get; set; }
|
||||||
public string? Icon { get; set; }
|
public ActivityTraits Traits { get; set; }
|
||||||
public string[] Outcomes { get; set; }
|
public string[] Outcomes { get; set; }
|
||||||
public ActivityPropertyDescriptor[] Properties { get; set; }
|
public ActivityPropertyDescriptor[] Properties { get; set; }
|
||||||
}
|
}
|
||||||
|
|
|
||||||
12
src/core/Elsa.Abstractions/Metadata/ActivityTraits.cs
Normal file
12
src/core/Elsa.Abstractions/Metadata/ActivityTraits.cs
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Elsa.Metadata
|
||||||
|
{
|
||||||
|
[Flags]
|
||||||
|
public enum ActivityTraits
|
||||||
|
{
|
||||||
|
Action = 1,
|
||||||
|
Trigger = 2,
|
||||||
|
Job = 4
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -6,10 +6,9 @@ using Elsa.Services.Models;
|
||||||
// ReSharper disable once CheckNamespace
|
// ReSharper disable once CheckNamespace
|
||||||
namespace Elsa.Activities.ControlFlow
|
namespace Elsa.Activities.ControlFlow
|
||||||
{
|
{
|
||||||
[ActivityDefinition(
|
[Activity(
|
||||||
Category = "Workflows",
|
Category = "Workflows",
|
||||||
Description = "Removes any blocking activities and sets the status of the workflow to Completed.",
|
Description = "Removes any blocking activities and sets the status of the workflow to Completed."
|
||||||
Icon = "fas fa-flag-checkered"
|
|
||||||
)]
|
)]
|
||||||
public class Finish : Activity
|
public class Finish : Activity
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -7,10 +7,9 @@ using Elsa.Services.Models;
|
||||||
// ReSharper disable once CheckNamespace
|
// ReSharper disable once CheckNamespace
|
||||||
namespace Elsa.Activities.ControlFlow
|
namespace Elsa.Activities.ControlFlow
|
||||||
{
|
{
|
||||||
[ActivityDefinition(
|
[Activity(
|
||||||
Category = "Control Flow",
|
Category = "Control Flow",
|
||||||
Description = "Iterate between two numbers.",
|
Description = "Iterate between two numbers.",
|
||||||
Icon = "far fa-circle",
|
|
||||||
Outcomes = new[] { OutcomeNames.Iterate, OutcomeNames.Done }
|
Outcomes = new[] { OutcomeNames.Iterate, OutcomeNames.Done }
|
||||||
)]
|
)]
|
||||||
public class For : Activity
|
public class For : Activity
|
||||||
|
|
|
||||||
|
|
@ -9,10 +9,9 @@ using Elsa.Services.Models;
|
||||||
// ReSharper disable once CheckNamespace
|
// ReSharper disable once CheckNamespace
|
||||||
namespace Elsa.Activities.ControlFlow
|
namespace Elsa.Activities.ControlFlow
|
||||||
{
|
{
|
||||||
[ActivityDefinition(
|
[Activity(
|
||||||
Category = "Control Flow",
|
Category = "Control Flow",
|
||||||
Description = "Iterate over a collection.",
|
Description = "Iterate over a collection.",
|
||||||
Icon = "far fa-circle",
|
|
||||||
Outcomes = new[] { OutcomeNames.Iterate, OutcomeNames.Done }
|
Outcomes = new[] { OutcomeNames.Iterate, OutcomeNames.Done }
|
||||||
)]
|
)]
|
||||||
public class ForEach : Activity
|
public class ForEach : Activity
|
||||||
|
|
|
||||||
|
|
@ -6,10 +6,9 @@ using Elsa.Services;
|
||||||
// ReSharper disable once CheckNamespace
|
// ReSharper disable once CheckNamespace
|
||||||
namespace Elsa.Activities.ControlFlow
|
namespace Elsa.Activities.ControlFlow
|
||||||
{
|
{
|
||||||
[ActivityDefinition(
|
[Activity(
|
||||||
Category = "Control Flow",
|
Category = "Control Flow",
|
||||||
Description = "Fork workflow execution into multiple branches.",
|
Description = "Fork workflow execution into multiple branches.",
|
||||||
Icon = "fas fa-code-branch fa-rotate-180",
|
|
||||||
Outcomes = new[] { "x => x.state.branches" })]
|
Outcomes = new[] { "x => x.state.branches" })]
|
||||||
public class Fork : Activity
|
public class Fork : Activity
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -6,11 +6,10 @@ using Elsa.Services.Models;
|
||||||
// ReSharper disable once CheckNamespace
|
// ReSharper disable once CheckNamespace
|
||||||
namespace Elsa.Activities.ControlFlow
|
namespace Elsa.Activities.ControlFlow
|
||||||
{
|
{
|
||||||
[ActivityDefinition(
|
[Activity(
|
||||||
DisplayName = "If/Else",
|
DisplayName = "If/Else",
|
||||||
Category = "Control Flow",
|
Category = "Control Flow",
|
||||||
Description = "Evaluate a Boolean expression and continue execution depending on the result.",
|
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[] { True, False, OutcomeNames.Done }
|
Outcomes = new[] { True, False, OutcomeNames.Done }
|
||||||
)]
|
)]
|
||||||
public class IfElse : Activity
|
public class IfElse : Activity
|
||||||
|
|
|
||||||
|
|
@ -13,11 +13,9 @@ using MediatR;
|
||||||
// ReSharper disable once CheckNamespace
|
// ReSharper disable once CheckNamespace
|
||||||
namespace Elsa.Activities.ControlFlow
|
namespace Elsa.Activities.ControlFlow
|
||||||
{
|
{
|
||||||
[ActivityDefinition(
|
[Activity(
|
||||||
Category = "Control Flow",
|
Category = "Control Flow",
|
||||||
Description = "Merge workflow execution back into a single branch.",
|
Description = "Merge workflow execution back into a single branch.",
|
||||||
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 }
|
Outcomes = new[] { OutcomeNames.Done }
|
||||||
)]
|
)]
|
||||||
public class Join : Activity, INotificationHandler<ActivityExecuted>
|
public class Join : Activity, INotificationHandler<ActivityExecuted>
|
||||||
|
|
|
||||||
|
|
@ -9,10 +9,9 @@ using Elsa.Services.Models;
|
||||||
// ReSharper disable once CheckNamespace
|
// ReSharper disable once CheckNamespace
|
||||||
namespace Elsa.Activities.ControlFlow
|
namespace Elsa.Activities.ControlFlow
|
||||||
{
|
{
|
||||||
[ActivityDefinition(
|
[Activity(
|
||||||
Category = "Control Flow",
|
Category = "Control Flow",
|
||||||
Description = "Iterate over a collection in parallel.",
|
Description = "Iterate over a collection in parallel.",
|
||||||
Icon = "far fa-circle",
|
|
||||||
Outcomes = new[] { OutcomeNames.Iterate, OutcomeNames.Done }
|
Outcomes = new[] { OutcomeNames.Iterate, OutcomeNames.Done }
|
||||||
)]
|
)]
|
||||||
public class ParallelForEach : Activity
|
public class ParallelForEach : Activity
|
||||||
|
|
|
||||||
|
|
@ -8,12 +8,9 @@ using Elsa.Services.Models;
|
||||||
// ReSharper disable once CheckNamespace
|
// ReSharper disable once CheckNamespace
|
||||||
namespace Elsa.Activities.ControlFlow
|
namespace Elsa.Activities.ControlFlow
|
||||||
{
|
{
|
||||||
[ActivityDefinition(
|
[Activity(
|
||||||
Category = "Control Flow",
|
Category = "Control Flow",
|
||||||
Description = "Switch execution based on a given expression.",
|
Description = "Switch execution based on a given expression."
|
||||||
Icon = "far fa-list-alt",
|
|
||||||
RuntimeDescription = "x => !!x.state.expression ? `Switch execution based on <strong>${ x.state.expression.expression }</strong>.` : x.definition.description",
|
|
||||||
Outcomes = new[] { "x => x.state.cases.map(c => c.toString())" }
|
|
||||||
)]
|
)]
|
||||||
public class Switch : Activity
|
public class Switch : Activity
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -6,10 +6,9 @@ using Elsa.Services.Models;
|
||||||
// ReSharper disable once CheckNamespace
|
// ReSharper disable once CheckNamespace
|
||||||
namespace Elsa.Activities.ControlFlow
|
namespace Elsa.Activities.ControlFlow
|
||||||
{
|
{
|
||||||
[ActivityDefinition(
|
[Activity(
|
||||||
Category = "Control Flow",
|
Category = "Control Flow",
|
||||||
Description = "Execute while a given condition is true.",
|
Description = "Execute while a given condition is true.",
|
||||||
Icon = "far fa-circle",
|
|
||||||
Outcomes = new[] { OutcomeNames.Iterate, OutcomeNames.Done }
|
Outcomes = new[] { OutcomeNames.Iterate, OutcomeNames.Done }
|
||||||
)]
|
)]
|
||||||
public class While : Activity
|
public class While : Activity
|
||||||
|
|
|
||||||
|
|
@ -8,10 +8,10 @@ namespace Elsa.Activities.Primitives
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Sets the CorrelationId of the workflow to a given value.
|
/// Sets the CorrelationId of the workflow to a given value.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[ActivityDefinition(
|
[Activity(
|
||||||
Category = "Workflows",
|
Category = "Workflows",
|
||||||
Description = "Set the CorrelationId of the workflow to a given value.",
|
Description = "Set the CorrelationId of the workflow to a given value.",
|
||||||
Icon = "fas fa-link"
|
Outcomes = new[] { OutcomeNames.Done }
|
||||||
)]
|
)]
|
||||||
public class Correlate : Activity
|
public class Correlate : Activity
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -6,11 +6,10 @@ using Elsa.Services.Models;
|
||||||
// ReSharper disable once CheckNamespace
|
// ReSharper disable once CheckNamespace
|
||||||
namespace Elsa.Activities.Primitives
|
namespace Elsa.Activities.Primitives
|
||||||
{
|
{
|
||||||
[ActivityDefinition(
|
[Activity(
|
||||||
DisplayName = "Set Variable",
|
DisplayName = "Set Variable",
|
||||||
Description = "Set variable on the workflow.",
|
Description = "Set variable on the workflow.",
|
||||||
Category = "Primitives",
|
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 }
|
Outcomes = new[] { OutcomeNames.Done }
|
||||||
)]
|
)]
|
||||||
public class SetVariable : Activity
|
public class SetVariable : Activity
|
||||||
|
|
|
||||||
|
|
@ -11,10 +11,10 @@ namespace Elsa.Activities.Signaling
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Suspends workflow execution until the specified signal is received.
|
/// Suspends workflow execution until the specified signal is received.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[ActivityDefinition(
|
[Trigger(
|
||||||
Category = "Workflows",
|
Category = "Workflows",
|
||||||
Description = "Halt workflow execution until the specified signal is received.",
|
Description = "Suspend workflow execution until the specified signal is received.",
|
||||||
Icon = "fas fa-traffic-light"
|
Outcomes = new[] { OutcomeNames.Done }
|
||||||
)]
|
)]
|
||||||
public class ReceiveSignal : Activity
|
public class ReceiveSignal : Activity
|
||||||
{
|
{
|
||||||
|
|
@ -25,7 +25,7 @@ namespace Elsa.Activities.Signaling
|
||||||
{
|
{
|
||||||
if (context.Input is Signal triggeredSignal)
|
if (context.Input is Signal triggeredSignal)
|
||||||
return string.Equals(triggeredSignal.SignalName, Signal, StringComparison.OrdinalIgnoreCase);
|
return string.Equals(triggeredSignal.SignalName, Signal, StringComparison.OrdinalIgnoreCase);
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -12,10 +12,10 @@ namespace Elsa.Activities.Signaling
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Triggers the specified signal.
|
/// Triggers the specified signal.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[ActivityDefinition(
|
[Action(
|
||||||
Category = "Workflows",
|
Category = "Workflows",
|
||||||
Description = "Sends the specified signal.",
|
Description = "Sends the specified signal.",
|
||||||
Icon = "fas fa-broadcast-tower"
|
Outcomes = new[] { OutcomeNames.Done }
|
||||||
)]
|
)]
|
||||||
public class SendSignal : Activity
|
public class SendSignal : Activity
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ using Open.Linq.AsyncExtensions;
|
||||||
// ReSharper disable once CheckNamespace
|
// ReSharper disable once CheckNamespace
|
||||||
namespace Elsa.Activities.Workflows
|
namespace Elsa.Activities.Workflows
|
||||||
{
|
{
|
||||||
[ActivityDefinition(
|
[Activity(
|
||||||
Category = "Workflows",
|
Category = "Workflows",
|
||||||
Description = "Runs a child workflow."
|
Description = "Runs a child workflow."
|
||||||
)]
|
)]
|
||||||
|
|
|
||||||
|
|
@ -21,18 +21,17 @@ namespace Elsa.Metadata
|
||||||
|
|
||||||
public ActivityDescriptor Describe(Type activityType)
|
public ActivityDescriptor Describe(Type activityType)
|
||||||
{
|
{
|
||||||
var activityDefinitionAttribute = activityType.GetCustomAttribute<ActivityDefinitionAttribute>();
|
var activityAttribute = activityType.GetCustomAttribute<ActivityAttribute>();
|
||||||
var typeName = activityDefinitionAttribute?.Type ?? activityType.Name;
|
var typeName = activityAttribute?.Type ?? activityType.Name;
|
||||||
|
|
||||||
var displayName =
|
var displayName =
|
||||||
activityDefinitionAttribute?.DisplayName ??
|
activityAttribute?.DisplayName ??
|
||||||
activityType.Name.Humanize(LetterCasing.Title);
|
activityType.Name.Humanize(LetterCasing.Title);
|
||||||
|
|
||||||
var description = activityDefinitionAttribute?.Description;
|
var description = activityAttribute?.Description;
|
||||||
var runtimeDescription = activityDefinitionAttribute?.RuntimeDescription;
|
var category = activityAttribute?.Category ?? "Miscellaneous";
|
||||||
var category = activityDefinitionAttribute?.Category ?? "Miscellaneous";
|
var traits = activityAttribute?.Traits ?? ActivityTraits.Action;
|
||||||
var icon = activityDefinitionAttribute?.Icon;
|
var outcomes = activityAttribute?.Outcomes ?? new[] { OutcomeNames.Done };
|
||||||
var outcomes = activityDefinitionAttribute?.Outcomes ?? new[] { OutcomeNames.Done };
|
|
||||||
var properties = DescribeProperties(activityType);
|
var properties = DescribeProperties(activityType);
|
||||||
|
|
||||||
return new ActivityDescriptor
|
return new ActivityDescriptor
|
||||||
|
|
@ -40,9 +39,8 @@ namespace Elsa.Metadata
|
||||||
Type = typeName.Pascalize(),
|
Type = typeName.Pascalize(),
|
||||||
DisplayName = displayName,
|
DisplayName = displayName,
|
||||||
Description = description,
|
Description = description,
|
||||||
RuntimeDescription = runtimeDescription,
|
|
||||||
Category = category,
|
Category = category,
|
||||||
Icon = icon,
|
Traits = traits,
|
||||||
Properties = properties.ToArray(),
|
Properties = properties.ToArray(),
|
||||||
Outcomes = outcomes
|
Outcomes = outcomes
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ namespace ElsaDashboard.Application.Server
|
||||||
{
|
{
|
||||||
public class Program
|
public class Program
|
||||||
{
|
{
|
||||||
public static bool UseBlazorServer = false;
|
public static bool UseBlazorServer = true;
|
||||||
public static bool UseBlazorWebAssembly => !UseBlazorServer;
|
public static bool UseBlazorWebAssembly => !UseBlazorServer;
|
||||||
public static RenderMode RenderMode => UseBlazorServer ? RenderMode.ServerPrerendered: RenderMode.WebAssemblyPrerendered;
|
public static RenderMode RenderMode => UseBlazorServer ? RenderMode.ServerPrerendered: RenderMode.WebAssemblyPrerendered;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -9,26 +9,20 @@
|
||||||
<line x1="21" y1="21" x2="15" y2="15"/>
|
<line x1="21" y1="21" x2="15" y2="15"/>
|
||||||
</svg>
|
</svg>
|
||||||
</div>
|
</div>
|
||||||
<input class="form-input block w-full pl-10 sm:text-sm sm:leading-5"placeholder="Search activities">
|
<input type="text" @bind="ActivitySearchText" @bind:event="oninput" class="form-input block w-full pl-10 sm:text-sm sm:leading-5" placeholder="Search activities">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="border-b border-gray-200">
|
<div class="border-b border-gray-200">
|
||||||
<div class="px-6">
|
<div class="px-6">
|
||||||
<nav class="-mb-px flex space-x-6" x-descriptions="Tab component">
|
<nav class="-mb-px flex space-x-6" x-descriptions="Tab component">
|
||||||
<a href="#"
|
@foreach (var activityTypeFilter in ActivityTraitFilters)
|
||||||
class="whitespace-no-wrap pb-4 px-1 border-b-2 border-blue-500 font-medium text-sm leading-5 text-blue-600 focus:outline-none focus:text-blue-800 focus:border-blue-700"
|
{
|
||||||
aria-current="page">
|
var activeClass = activityTypeFilter == SelectedActivityTraitFilter ? "border-blue-500 text-blue-600 focus:text-blue-800 focus:border-blue-700" : "border-transparent text-gray-500 focus:text-gray-700 focus:border-gray-300";
|
||||||
All
|
<a href="#" @onclick:preventDefault @onclick="@(() => OnActivityTypeFilterClick(activityTypeFilter))" class="whitespace-no-wrap pb-4 px-1 border-b-2 font-medium text-sm leading-5 focus:outline-none @activeClass" aria-current="page">
|
||||||
</a>
|
@activityTypeFilter.ToString()
|
||||||
<a href="#"
|
</a>
|
||||||
class="whitespace-no-wrap pb-4 px-1 border-b-2 border-transparent font-medium text-sm leading-5 text-gray-500 hover:text-gray-700 hover:border-gray-300 focus:outline-none focus:text-gray-700 focus:border-gray-300">
|
}
|
||||||
Actions
|
|
||||||
</a>
|
|
||||||
<a href="#"
|
|
||||||
class="whitespace-no-wrap pb-4 px-1 border-b-2 border-transparent font-medium text-sm leading-5 text-gray-500 hover:text-gray-700 hover:border-gray-300 focus:outline-none focus:text-gray-700 focus:border-gray-300">
|
|
||||||
Triggers
|
|
||||||
</a>
|
|
||||||
</nav>
|
</nav>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -1,21 +1,61 @@
|
||||||
using System.Collections.Generic;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Elsa.Client.Models;
|
using Elsa.Client.Models;
|
||||||
using ElsaDashboard.Shared.Rpc;
|
using ElsaDashboard.Shared.Rpc;
|
||||||
using Microsoft.AspNetCore.Components;
|
using Microsoft.AspNetCore.Components;
|
||||||
|
using Microsoft.AspNetCore.Components.Web;
|
||||||
|
|
||||||
namespace ElsaDashboard.Application.Pages.Designer
|
namespace ElsaDashboard.Application.Pages.Designer
|
||||||
{
|
{
|
||||||
partial class ActivityPicker
|
partial class ActivityPicker
|
||||||
{
|
{
|
||||||
[Inject] private IActivityService ActivityService { get; set; } = default!;
|
[Inject] private IActivityService ActivityService { get; set; } = default!;
|
||||||
private ICollection<IGrouping<string, ActivityDescriptor>> ActivityGroupings { get; set; } = new System.Collections.Generic.List<IGrouping<string, ActivityDescriptor>>();
|
private ActivityTraitFilter SelectedActivityTraitFilter { get; set; }
|
||||||
|
private string? ActivitySearchText { get; set; }
|
||||||
|
private ICollection<ActivityTraitFilter> ActivityTraitFilters => new[] { ActivityTraitFilter.All, ActivityTraitFilter.Actions, ActivityTraitFilter.Triggers };
|
||||||
|
private ICollection<ActivityDescriptor> Activities { get; set; } = new System.Collections.Generic.List<ActivityDescriptor>();
|
||||||
|
|
||||||
|
private ICollection<IGrouping<string, ActivityDescriptor>> ActivityGroupings =>
|
||||||
|
FilterBySearchText(
|
||||||
|
FilterByTrait(Activities, SelectedActivityTraitFilter),
|
||||||
|
ActivitySearchText)
|
||||||
|
.GroupBy(x => x.Category)
|
||||||
|
.ToList();
|
||||||
|
|
||||||
protected override async Task OnInitializedAsync()
|
protected override async Task OnInitializedAsync()
|
||||||
{
|
{
|
||||||
var response = (await ActivityService.GetActivitiesAsync());
|
var response = (await ActivityService.GetActivitiesAsync());
|
||||||
ActivityGroupings = response.Activities.GroupBy(x => x.Category).ToList();
|
Activities = response.Activities.ToList();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnActivityTypeFilterClick(ActivityTraitFilter activityTraitFilter)
|
||||||
|
{
|
||||||
|
SelectedActivityTraitFilter = activityTraitFilter;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static IEnumerable<ActivityDescriptor> FilterByTrait(IEnumerable<ActivityDescriptor> activities, ActivityTraitFilter filter) =>
|
||||||
|
filter switch
|
||||||
|
{
|
||||||
|
ActivityTraitFilter.Actions => activities.Where(x => (x.Traits & ActivityTraits.Action) == ActivityTraits.Action),
|
||||||
|
ActivityTraitFilter.Triggers => activities.Where(x => (x.Traits & ActivityTraits.Trigger) == ActivityTraits.Trigger),
|
||||||
|
ActivityTraitFilter.All => activities,
|
||||||
|
_ => activities
|
||||||
|
};
|
||||||
|
|
||||||
|
private static IEnumerable<ActivityDescriptor> FilterBySearchText(IEnumerable<ActivityDescriptor> activities, string? searchText)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(searchText))
|
||||||
|
return activities;
|
||||||
|
|
||||||
|
return
|
||||||
|
from activity in activities
|
||||||
|
where
|
||||||
|
(activity.Description ?? "").Contains(searchText, StringComparison.InvariantCultureIgnoreCase) ||
|
||||||
|
(activity.DisplayName ?? "").Contains(searchText, StringComparison.InvariantCultureIgnoreCase) ||
|
||||||
|
activity.Type.Contains(searchText, StringComparison.InvariantCultureIgnoreCase)
|
||||||
|
select activity;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -0,0 +1,9 @@
|
||||||
|
namespace ElsaDashboard.Application.Pages.Designer
|
||||||
|
{
|
||||||
|
public enum ActivityTraitFilter
|
||||||
|
{
|
||||||
|
All,
|
||||||
|
Actions,
|
||||||
|
Triggers
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in a new issue