diff --git a/.editorconfig b/.editorconfig index 5cc8f95ea..17ab15ef1 100644 --- a/.editorconfig +++ b/.editorconfig @@ -9,6 +9,7 @@ indent_size=4 # ReSharper properties resharper_csharp_max_line_length=240 resharper_keep_user_linebreaks=true +resharper_space_within_single_line_array_initializer_braces=true # Microsoft .NET properties csharp_new_line_before_members_in_object_initializers=false diff --git a/src/activities/Elsa.Activities.Console/Activities/ReadLine/ReadLine.cs b/src/activities/Elsa.Activities.Console/Activities/ReadLine/ReadLine.cs index a441f0956..d60331d56 100644 --- a/src/activities/Elsa.Activities.Console/Activities/ReadLine/ReadLine.cs +++ b/src/activities/Elsa.Activities.Console/Activities/ReadLine/ReadLine.cs @@ -12,10 +12,9 @@ namespace Elsa.Activities.Console /// /// Reads input from the console. /// - [ActivityDefinition( + [Action( Category = "Console", Description = "Read text from standard in.", - Icon = "fas fa-terminal", Outcomes = new[] { OutcomeNames.Done } )] public class ReadLine : Activity @@ -44,7 +43,7 @@ namespace Elsa.Activities.Console protected override IActivityExecutionResult OnResume(ActivityExecutionContext context) { - var receivedInput = (string)context.Input!; + var receivedInput = (string) context.Input!; return Execute(receivedInput); } diff --git a/src/activities/Elsa.Activities.Console/Activities/WriteLine/WriteLine.cs b/src/activities/Elsa.Activities.Console/Activities/WriteLine/WriteLine.cs index 681a8c530..2cc10fa93 100644 --- a/src/activities/Elsa.Activities.Console/Activities/WriteLine/WriteLine.cs +++ b/src/activities/Elsa.Activities.Console/Activities/WriteLine/WriteLine.cs @@ -12,10 +12,9 @@ namespace Elsa.Activities.Console /// /// Writes a text string to the console. /// - [ActivityDefinition( + [Action( Category = "Console", Description = "Write text to standard out.", - Icon = "fas fa-terminal", Outcomes = new[] { OutcomeNames.Done } )] public class WriteLine : Activity diff --git a/src/activities/Elsa.Activities.Dropbox/Activities/SaveToDropbox.cs b/src/activities/Elsa.Activities.Dropbox/Activities/SaveToDropbox.cs index beb2dca3c..9077027d1 100644 --- a/src/activities/Elsa.Activities.Dropbox/Activities/SaveToDropbox.cs +++ b/src/activities/Elsa.Activities.Dropbox/Activities/SaveToDropbox.cs @@ -9,10 +9,11 @@ using Elsa.Services.Models; namespace Elsa.Activities.Dropbox.Activities { - [ActivityDefinition( + [Action( Category = "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 { private readonly IFilesApi _filesApi; diff --git a/src/activities/Elsa.Activities.Email/Activities/SendEmail/SendEmail.cs b/src/activities/Elsa.Activities.Email/Activities/SendEmail/SendEmail.cs index 3700f0070..ab39e5c27 100644 --- a/src/activities/Elsa.Activities.Email/Activities/SendEmail/SendEmail.cs +++ b/src/activities/Elsa.Activities.Email/Activities/SendEmail/SendEmail.cs @@ -11,7 +11,7 @@ using MimeKit.Text; // ReSharper disable once CheckNamespace namespace Elsa.Activities.Email { - [ActivityDefinition(Category = "Email", Description = "Send an email message.")] + [Action(Category = "Email", Description = "Send an email message.")] public class SendEmail : Activity { private readonly ISmtpService _smtpService; diff --git a/src/activities/Elsa.Activities.Http/Activities/ReceiveHttpRequest/ReceiveHttpRequest.cs b/src/activities/Elsa.Activities.Http/Activities/ReceiveHttpRequest/ReceiveHttpRequest.cs index b09c35922..26f51e713 100644 --- a/src/activities/Elsa.Activities.Http/Activities/ReceiveHttpRequest/ReceiveHttpRequest.cs +++ b/src/activities/Elsa.Activities.Http/Activities/ReceiveHttpRequest/ReceiveHttpRequest.cs @@ -15,11 +15,10 @@ using Microsoft.AspNetCore.Http; // ReSharper disable once CheckNamespace namespace Elsa.Activities.Http { - [ActivityDefinition( + [Trigger( Category = "HTTP", DisplayName = "Receive HTTP Request", Description = "Receive an incoming HTTP request.", - RuntimeDescription = "x => !!x.state.path ? `Handle ${ x.state.method } ${ x.state.path }.` : x.definition.description", Outcomes = new[] { OutcomeNames.Done } )] public class ReceiveHttpRequest : Activity diff --git a/src/activities/Elsa.Activities.Http/Activities/Redirect/Redirect.cs b/src/activities/Elsa.Activities.Http/Activities/Redirect/Redirect.cs index 8f7dfe4d2..135679274 100644 --- a/src/activities/Elsa.Activities.Http/Activities/Redirect/Redirect.cs +++ b/src/activities/Elsa.Activities.Http/Activities/Redirect/Redirect.cs @@ -10,7 +10,7 @@ using Microsoft.Extensions.Localization; // ReSharper disable once CheckNamespace namespace Elsa.Activities.Http { - [ActivityDefinition( + [Action( Category = "HTTP", DisplayName = "Redirect", Description = "Write an HTTP redirect response.", diff --git a/src/activities/Elsa.Activities.Http/Activities/SendHttpRequest/SendHttpRequest.cs b/src/activities/Elsa.Activities.Http/Activities/SendHttpRequest/SendHttpRequest.cs index 4ac83641a..31f0ad22d 100644 --- a/src/activities/Elsa.Activities.Http/Activities/SendHttpRequest/SendHttpRequest.cs +++ b/src/activities/Elsa.Activities.Http/Activities/SendHttpRequest/SendHttpRequest.cs @@ -19,15 +19,11 @@ using HttpRequestHeaders = Elsa.Activities.Http.Models.HttpRequestHeaders; // ReSharper disable once CheckNamespace namespace Elsa.Activities.Http { - [ActivityDefinition( + [Action( Category = "HTTP", DisplayName = "Send HTTP Request", Description = "Send an HTTP request.", - Outcomes = new[] - { - OutcomeNames.Done, - "x => !!x.state.supportedStatusCodes ? ['UnSupportedStatusCode', ...x.state.supportedStatusCodes] : ['UnSupportedStatusCode']" - } + Outcomes = new[] { OutcomeNames.Done } )] public class SendHttpRequest : Activity { diff --git a/src/activities/Elsa.Activities.Http/Activities/WriteHttpResponse/WriteHttpResponse.cs b/src/activities/Elsa.Activities.Http/Activities/WriteHttpResponse/WriteHttpResponse.cs index 65a0e3b0b..baff9e5cc 100644 --- a/src/activities/Elsa.Activities.Http/Activities/WriteHttpResponse/WriteHttpResponse.cs +++ b/src/activities/Elsa.Activities.Http/Activities/WriteHttpResponse/WriteHttpResponse.cs @@ -13,7 +13,7 @@ using Microsoft.Extensions.Localization; // ReSharper disable once CheckNamespace namespace Elsa.Activities.Http { - [ActivityDefinition( + [Action( Category = "HTTP", DisplayName = "Write HTTP Response", Description = "Write an HTTP response.", diff --git a/src/activities/Elsa.Activities.MassTransit/Activities/CancelScheduledMassTransitMessage/CancelScheduledMassTransitMessage.cs b/src/activities/Elsa.Activities.MassTransit/Activities/CancelScheduledMassTransitMessage/CancelScheduledMassTransitMessage.cs index 08a1b3411..e2a5d99a4 100644 --- a/src/activities/Elsa.Activities.MassTransit/Activities/CancelScheduledMassTransitMessage/CancelScheduledMassTransitMessage.cs +++ b/src/activities/Elsa.Activities.MassTransit/Activities/CancelScheduledMassTransitMessage/CancelScheduledMassTransitMessage.cs @@ -10,7 +10,7 @@ using Microsoft.Extensions.Options; // ReSharper disable once CheckNamespace namespace Elsa.Activities.MassTransit { - [ActivityDefinition( + [Action( Category = "MassTransit", DisplayName = "Cancel scheduled MassTransit Message", Description = "Cancel a scheduled message via MassTransit." diff --git a/src/activities/Elsa.Activities.MassTransit/Activities/PublishMassTransitMessage/PublishMassTransitMessage.cs b/src/activities/Elsa.Activities.MassTransit/Activities/PublishMassTransitMessage/PublishMassTransitMessage.cs index 765c207a4..aed4284f6 100644 --- a/src/activities/Elsa.Activities.MassTransit/Activities/PublishMassTransitMessage/PublishMassTransitMessage.cs +++ b/src/activities/Elsa.Activities.MassTransit/Activities/PublishMassTransitMessage/PublishMassTransitMessage.cs @@ -8,7 +8,7 @@ using MassTransit; // ReSharper disable once CheckNamespace namespace Elsa.Activities.MassTransit { - [ActivityDefinition( + [Action( Category = "MassTransit", DisplayName = "Publish MassTransit Message", Description = "Publish an event via MassTransit." diff --git a/src/activities/Elsa.Activities.MassTransit/Activities/ReceiveMassTransitMessage/ReceiveMassTransitMessage.cs b/src/activities/Elsa.Activities.MassTransit/Activities/ReceiveMassTransitMessage/ReceiveMassTransitMessage.cs index d4f8b462c..6a2836403 100644 --- a/src/activities/Elsa.Activities.MassTransit/Activities/ReceiveMassTransitMessage/ReceiveMassTransitMessage.cs +++ b/src/activities/Elsa.Activities.MassTransit/Activities/ReceiveMassTransitMessage/ReceiveMassTransitMessage.cs @@ -7,7 +7,7 @@ using Elsa.Services.Models; // ReSharper disable once CheckNamespace namespace Elsa.Activities.MassTransit { - [ActivityDefinition( + [Trigger( Category = "MassTransit", DisplayName = "Receive MassTransit Message", Description = "Receive a message via MassTransit." diff --git a/src/activities/Elsa.Activities.MassTransit/Activities/ScheduleSendMassTransitMessage/ScheduleSendMassTransitMessage.cs b/src/activities/Elsa.Activities.MassTransit/Activities/ScheduleSendMassTransitMessage/ScheduleSendMassTransitMessage.cs index 9c800fe66..042b1871a 100644 --- a/src/activities/Elsa.Activities.MassTransit/Activities/ScheduleSendMassTransitMessage/ScheduleSendMassTransitMessage.cs +++ b/src/activities/Elsa.Activities.MassTransit/Activities/ScheduleSendMassTransitMessage/ScheduleSendMassTransitMessage.cs @@ -13,7 +13,7 @@ using NodaTime; // ReSharper disable once CheckNamespace namespace Elsa.Activities.MassTransit { - [ActivityDefinition( + [Action( Category = "MassTransit", DisplayName = "Schedule MassTransit Message", Description = "Schedule a message via MassTransit." diff --git a/src/activities/Elsa.Activities.MassTransit/Activities/SendMassTransitMessage/SendMassTransitMessage.cs b/src/activities/Elsa.Activities.MassTransit/Activities/SendMassTransitMessage/SendMassTransitMessage.cs index 0c91d7039..f376f2631 100644 --- a/src/activities/Elsa.Activities.MassTransit/Activities/SendMassTransitMessage/SendMassTransitMessage.cs +++ b/src/activities/Elsa.Activities.MassTransit/Activities/SendMassTransitMessage/SendMassTransitMessage.cs @@ -9,7 +9,7 @@ using MassTransit; // ReSharper disable once CheckNamespace namespace Elsa.Activities.MassTransit { - [ActivityDefinition( + [Action( Category = "MassTransit", DisplayName = "Send MassTransit Message", Description = "Send a message via MassTransit." diff --git a/src/activities/Elsa.Activities.Timers/Activities/CronEvent/CronEvent.cs b/src/activities/Elsa.Activities.Timers/Activities/CronEvent/CronEvent.cs index 5b3a7eb94..1b83866ce 100644 --- a/src/activities/Elsa.Activities.Timers/Activities/CronEvent/CronEvent.cs +++ b/src/activities/Elsa.Activities.Timers/Activities/CronEvent/CronEvent.cs @@ -6,18 +6,17 @@ using Elsa.Services.Models; // ReSharper disable once CheckNamespace namespace Elsa.Activities.Timers { - [ActivityDefinition( + [Trigger( Category = "Timers", Description = "Triggers periodically based on a specified CRON expression.", - RuntimeDescription = "x => !!x.state.cronExpression ? `${ x.state.cronExpression.expression }.` : x.definition.description", Outcomes = new[] { OutcomeNames.Done } )] public class CronEvent : Activity { [ActivityProperty(Hint = "Specify a CRON expression. See https://crontab.guru/ for help.")] 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(); } } \ No newline at end of file diff --git a/src/activities/Elsa.Activities.Timers/Activities/InstantEvent/InstantEvent.cs b/src/activities/Elsa.Activities.Timers/Activities/InstantEvent/InstantEvent.cs index e6828e7e3..435c9bb23 100644 --- a/src/activities/Elsa.Activities.Timers/Activities/InstantEvent/InstantEvent.cs +++ b/src/activities/Elsa.Activities.Timers/Activities/InstantEvent/InstantEvent.cs @@ -10,7 +10,7 @@ namespace Elsa.Activities.Timers /// /// Triggers at a specific instant in the future. /// - [ActivityDefinition( + [Trigger( Category = "Timers", Description = "Triggers at a specified moment in time." )] diff --git a/src/activities/Elsa.Activities.Timers/Activities/TimerEvent/TimerEvent.cs b/src/activities/Elsa.Activities.Timers/Activities/TimerEvent/TimerEvent.cs index 2fb0c5f70..5393f02d0 100644 --- a/src/activities/Elsa.Activities.Timers/Activities/TimerEvent/TimerEvent.cs +++ b/src/activities/Elsa.Activities.Timers/Activities/TimerEvent/TimerEvent.cs @@ -7,7 +7,7 @@ using NodaTime; // ReSharper disable once CheckNamespace 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 { [ActivityProperty(Hint = "An expression that evaluates to a Duration value.")] diff --git a/src/activities/Elsa.Activities.UserTask/Activities/UserTask.cs b/src/activities/Elsa.Activities.UserTask/Activities/UserTask.cs index 7530c9e03..a4c0a8a7d 100644 --- a/src/activities/Elsa.Activities.UserTask/Activities/UserTask.cs +++ b/src/activities/Elsa.Activities.UserTask/Activities/UserTask.cs @@ -13,7 +13,7 @@ namespace Elsa.Activities.UserTask.Activities /// /// Stores a set of possible user actions and halts the workflow until one of the actions has been performed. /// - [ActivityDefinition( + [Trigger( Category = "User Tasks", Description = "Triggers when a user action is received.", Outcomes = new[] { OutcomeNames.Done, "x => x.state.actions" } diff --git a/src/clients/Elsa.Client/Models/ActivityDescriptor.cs b/src/clients/Elsa.Client/Models/ActivityDescriptor.cs index d294cff16..847299874 100644 --- a/src/clients/Elsa.Client/Models/ActivityDescriptor.cs +++ b/src/clients/Elsa.Client/Models/ActivityDescriptor.cs @@ -8,10 +8,9 @@ namespace Elsa.Client.Models [DataMember(Order = 1)] public string Type { get; set; } = default!; [DataMember(Order = 2)] public string DisplayName { get; set; } = default!; [DataMember(Order = 3)] public string? Description { get; set; } - [DataMember(Order = 4)] public string? RuntimeDescription { get; set; } - [DataMember(Order = 5)] public string Category { get; set; } = default!; - [DataMember(Order = 6)] public string? Icon { get; set; } - [DataMember(Order = 7)] public string[] Outcomes { get; set; } = new string[0]; - [DataMember(Order = 8)] public ActivityPropertyDescriptor[] Properties { get; set; } = new ActivityPropertyDescriptor[0]; + [DataMember(Order = 4)] public string Category { get; set; } = default!; + [DataMember(Order = 5)] public ActivityTraits Traits { get; set; } + [DataMember(Order = 6)] public string[] Outcomes { get; set; } = new string[0]; + [DataMember(Order = 7)] public ActivityPropertyDescriptor[] Properties { get; set; } = new ActivityPropertyDescriptor[0]; } } \ No newline at end of file diff --git a/src/clients/Elsa.Client/Models/ActivityTraits.cs b/src/clients/Elsa.Client/Models/ActivityTraits.cs new file mode 100644 index 000000000..fb7197a3f --- /dev/null +++ b/src/clients/Elsa.Client/Models/ActivityTraits.cs @@ -0,0 +1,12 @@ +using System; + +namespace Elsa.Client.Models +{ + [Flags] + public enum ActivityTraits + { + Action = 1, + Trigger = 2, + Job = 4 + } +} \ No newline at end of file diff --git a/src/core/Elsa.Abstractions/Attributes/ActionAttribute.cs b/src/core/Elsa.Abstractions/Attributes/ActionAttribute.cs new file mode 100644 index 000000000..67594f126 --- /dev/null +++ b/src/core/Elsa.Abstractions/Attributes/ActionAttribute.cs @@ -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; + } + } +} \ No newline at end of file diff --git a/src/core/Elsa.Abstractions/Attributes/ActivityDefinitionAttribute.cs b/src/core/Elsa.Abstractions/Attributes/ActivityAttribute.cs similarity index 68% rename from src/core/Elsa.Abstractions/Attributes/ActivityDefinitionAttribute.cs rename to src/core/Elsa.Abstractions/Attributes/ActivityAttribute.cs index aeaaca271..78f433ea4 100644 --- a/src/core/Elsa.Abstractions/Attributes/ActivityDefinitionAttribute.cs +++ b/src/core/Elsa.Abstractions/Attributes/ActivityAttribute.cs @@ -1,16 +1,16 @@ using System; +using Elsa.Metadata; namespace Elsa.Attributes { [AttributeUsage(AttributeTargets.Class)] - public class ActivityDefinitionAttribute : Attribute + public class ActivityAttribute : Attribute { 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 ActivityTraits Traits { get; set; } = ActivityTraits.Action; public string[]? Outcomes { get; set; } } } \ No newline at end of file diff --git a/src/core/Elsa.Abstractions/Attributes/TriggerAttribute.cs b/src/core/Elsa.Abstractions/Attributes/TriggerAttribute.cs new file mode 100644 index 000000000..ce89f76a4 --- /dev/null +++ b/src/core/Elsa.Abstractions/Attributes/TriggerAttribute.cs @@ -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; + } + } +} \ No newline at end of file diff --git a/src/core/Elsa.Abstractions/Metadata/ActivityDescriptor.cs b/src/core/Elsa.Abstractions/Metadata/ActivityDescriptor.cs index 92c8b26c6..8f56b47d6 100644 --- a/src/core/Elsa.Abstractions/Metadata/ActivityDescriptor.cs +++ b/src/core/Elsa.Abstractions/Metadata/ActivityDescriptor.cs @@ -7,6 +7,7 @@ namespace Elsa.Metadata Type = "Activity"; Properties = new ActivityPropertyDescriptor[0]; Category = "Miscellaneous"; + Traits = ActivityTraits.Action; DisplayName = "Activity"; Properties = new ActivityPropertyDescriptor[0]; Outcomes = new string[0]; @@ -15,9 +16,8 @@ namespace Elsa.Metadata 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 ActivityTraits Traits { get; set; } public string[] Outcomes { get; set; } public ActivityPropertyDescriptor[] Properties { get; set; } } diff --git a/src/core/Elsa.Abstractions/Metadata/ActivityTraits.cs b/src/core/Elsa.Abstractions/Metadata/ActivityTraits.cs new file mode 100644 index 000000000..1f0094c04 --- /dev/null +++ b/src/core/Elsa.Abstractions/Metadata/ActivityTraits.cs @@ -0,0 +1,12 @@ +using System; + +namespace Elsa.Metadata +{ + [Flags] + public enum ActivityTraits + { + Action = 1, + Trigger = 2, + Job = 4 + } +} \ No newline at end of file diff --git a/src/core/Elsa.Core/Activities/ControlFlow/Finish/Finish.cs b/src/core/Elsa.Core/Activities/ControlFlow/Finish/Finish.cs index 61c445cde..7e8c994ee 100644 --- a/src/core/Elsa.Core/Activities/ControlFlow/Finish/Finish.cs +++ b/src/core/Elsa.Core/Activities/ControlFlow/Finish/Finish.cs @@ -6,10 +6,9 @@ using Elsa.Services.Models; // ReSharper disable once CheckNamespace namespace Elsa.Activities.ControlFlow { - [ActivityDefinition( + [Activity( Category = "Workflows", - Description = "Removes any blocking activities and sets the status of the workflow to Completed.", - Icon = "fas fa-flag-checkered" + Description = "Removes any blocking activities and sets the status of the workflow to Completed." )] public class Finish : Activity { diff --git a/src/core/Elsa.Core/Activities/ControlFlow/For/For.cs b/src/core/Elsa.Core/Activities/ControlFlow/For/For.cs index 679da4f75..1830bdb43 100644 --- a/src/core/Elsa.Core/Activities/ControlFlow/For/For.cs +++ b/src/core/Elsa.Core/Activities/ControlFlow/For/For.cs @@ -7,10 +7,9 @@ using Elsa.Services.Models; // ReSharper disable once CheckNamespace namespace Elsa.Activities.ControlFlow { - [ActivityDefinition( + [Activity( Category = "Control Flow", Description = "Iterate between two numbers.", - Icon = "far fa-circle", Outcomes = new[] { OutcomeNames.Iterate, OutcomeNames.Done } )] public class For : Activity diff --git a/src/core/Elsa.Core/Activities/ControlFlow/ForEach/ForEach.cs b/src/core/Elsa.Core/Activities/ControlFlow/ForEach/ForEach.cs index 9289ad7d1..80f455983 100644 --- a/src/core/Elsa.Core/Activities/ControlFlow/ForEach/ForEach.cs +++ b/src/core/Elsa.Core/Activities/ControlFlow/ForEach/ForEach.cs @@ -9,10 +9,9 @@ using Elsa.Services.Models; // ReSharper disable once CheckNamespace namespace Elsa.Activities.ControlFlow { - [ActivityDefinition( + [Activity( Category = "Control Flow", Description = "Iterate over a collection.", - Icon = "far fa-circle", Outcomes = new[] { OutcomeNames.Iterate, OutcomeNames.Done } )] public class ForEach : Activity diff --git a/src/core/Elsa.Core/Activities/ControlFlow/Fork/Fork.cs b/src/core/Elsa.Core/Activities/ControlFlow/Fork/Fork.cs index 5eadf593e..5cd97c5d6 100644 --- a/src/core/Elsa.Core/Activities/ControlFlow/Fork/Fork.cs +++ b/src/core/Elsa.Core/Activities/ControlFlow/Fork/Fork.cs @@ -6,10 +6,9 @@ using Elsa.Services; // ReSharper disable once CheckNamespace namespace Elsa.Activities.ControlFlow { - [ActivityDefinition( + [Activity( Category = "Control Flow", Description = "Fork workflow execution into multiple branches.", - Icon = "fas fa-code-branch fa-rotate-180", Outcomes = new[] { "x => x.state.branches" })] public class Fork : Activity { diff --git a/src/core/Elsa.Core/Activities/ControlFlow/IfElse/IfElse.cs b/src/core/Elsa.Core/Activities/ControlFlow/IfElse/IfElse.cs index e35d673a5..7d4644a35 100644 --- a/src/core/Elsa.Core/Activities/ControlFlow/IfElse/IfElse.cs +++ b/src/core/Elsa.Core/Activities/ControlFlow/IfElse/IfElse.cs @@ -6,11 +6,10 @@ using Elsa.Services.Models; // ReSharper disable once CheckNamespace namespace Elsa.Activities.ControlFlow { - [ActivityDefinition( + [Activity( DisplayName = "If/Else", Category = "Control Flow", Description = "Evaluate a Boolean expression and continue execution depending on the result.", - RuntimeDescription = "x => !!x.state.expression ? `Evaluate ${ x.state.expression.expression } and continue execution depending on the result.` : x.definition.description", Outcomes = new[] { True, False, OutcomeNames.Done } )] public class IfElse : Activity diff --git a/src/core/Elsa.Core/Activities/ControlFlow/Join/Join.cs b/src/core/Elsa.Core/Activities/ControlFlow/Join/Join.cs index 2c58376b2..de9ca2277 100644 --- a/src/core/Elsa.Core/Activities/ControlFlow/Join/Join.cs +++ b/src/core/Elsa.Core/Activities/ControlFlow/Join/Join.cs @@ -13,11 +13,9 @@ using MediatR; // ReSharper disable once CheckNamespace namespace Elsa.Activities.ControlFlow { - [ActivityDefinition( + [Activity( Category = "Control Flow", 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 ${ x.state.joinMode }` : x.definition.description", Outcomes = new[] { OutcomeNames.Done } )] public class Join : Activity, INotificationHandler diff --git a/src/core/Elsa.Core/Activities/ControlFlow/ParallelForEach/ParallelForEach.cs b/src/core/Elsa.Core/Activities/ControlFlow/ParallelForEach/ParallelForEach.cs index 0f09b13bb..1efd12b51 100644 --- a/src/core/Elsa.Core/Activities/ControlFlow/ParallelForEach/ParallelForEach.cs +++ b/src/core/Elsa.Core/Activities/ControlFlow/ParallelForEach/ParallelForEach.cs @@ -9,10 +9,9 @@ using Elsa.Services.Models; // ReSharper disable once CheckNamespace namespace Elsa.Activities.ControlFlow { - [ActivityDefinition( + [Activity( Category = "Control Flow", Description = "Iterate over a collection in parallel.", - Icon = "far fa-circle", Outcomes = new[] { OutcomeNames.Iterate, OutcomeNames.Done } )] public class ParallelForEach : Activity diff --git a/src/core/Elsa.Core/Activities/ControlFlow/Switch/Switch.cs b/src/core/Elsa.Core/Activities/ControlFlow/Switch/Switch.cs index 9b8dbd6a1..ea4194fd7 100644 --- a/src/core/Elsa.Core/Activities/ControlFlow/Switch/Switch.cs +++ b/src/core/Elsa.Core/Activities/ControlFlow/Switch/Switch.cs @@ -8,12 +8,9 @@ using Elsa.Services.Models; // ReSharper disable once CheckNamespace namespace Elsa.Activities.ControlFlow { - [ActivityDefinition( + [Activity( Category = "Control Flow", - Description = "Switch execution based on a given expression.", - Icon = "far fa-list-alt", - RuntimeDescription = "x => !!x.state.expression ? `Switch execution based on ${ x.state.expression.expression }.` : x.definition.description", - Outcomes = new[] { "x => x.state.cases.map(c => c.toString())" } + Description = "Switch execution based on a given expression." )] public class Switch : Activity { diff --git a/src/core/Elsa.Core/Activities/ControlFlow/While/While.cs b/src/core/Elsa.Core/Activities/ControlFlow/While/While.cs index c45e57e18..ed00744a5 100644 --- a/src/core/Elsa.Core/Activities/ControlFlow/While/While.cs +++ b/src/core/Elsa.Core/Activities/ControlFlow/While/While.cs @@ -6,10 +6,9 @@ using Elsa.Services.Models; // ReSharper disable once CheckNamespace namespace Elsa.Activities.ControlFlow { - [ActivityDefinition( + [Activity( Category = "Control Flow", Description = "Execute while a given condition is true.", - Icon = "far fa-circle", Outcomes = new[] { OutcomeNames.Iterate, OutcomeNames.Done } )] public class While : Activity diff --git a/src/core/Elsa.Core/Activities/Primitives/Correlate/Correlate.cs b/src/core/Elsa.Core/Activities/Primitives/Correlate/Correlate.cs index f9a1428d5..db2ff7765 100644 --- a/src/core/Elsa.Core/Activities/Primitives/Correlate/Correlate.cs +++ b/src/core/Elsa.Core/Activities/Primitives/Correlate/Correlate.cs @@ -8,10 +8,10 @@ namespace Elsa.Activities.Primitives /// /// Sets the CorrelationId of the workflow to a given value. /// - [ActivityDefinition( + [Activity( Category = "Workflows", Description = "Set the CorrelationId of the workflow to a given value.", - Icon = "fas fa-link" + Outcomes = new[] { OutcomeNames.Done } )] public class Correlate : Activity { diff --git a/src/core/Elsa.Core/Activities/Primitives/SetVariable/SetVariable.cs b/src/core/Elsa.Core/Activities/Primitives/SetVariable/SetVariable.cs index 7d905def4..1f1131c12 100644 --- a/src/core/Elsa.Core/Activities/Primitives/SetVariable/SetVariable.cs +++ b/src/core/Elsa.Core/Activities/Primitives/SetVariable/SetVariable.cs @@ -6,11 +6,10 @@ using Elsa.Services.Models; // ReSharper disable once CheckNamespace namespace Elsa.Activities.Primitives { - [ActivityDefinition( + [Activity( DisplayName = "Set Variable", Description = "Set variable on the workflow.", Category = "Primitives", - RuntimeDescription = "x => !!x.state.variableName ? `${x.state.variableName} = ${x.state.valueExpression.expression}
${x.state.valueExpression.syntax}` : x.definition.description", Outcomes = new[] { OutcomeNames.Done } )] public class SetVariable : Activity diff --git a/src/core/Elsa.Core/Activities/Signaling/ReceiveSignal/ReceiveSignal.cs b/src/core/Elsa.Core/Activities/Signaling/ReceiveSignal/ReceiveSignal.cs index b79751013..222a3d7eb 100644 --- a/src/core/Elsa.Core/Activities/Signaling/ReceiveSignal/ReceiveSignal.cs +++ b/src/core/Elsa.Core/Activities/Signaling/ReceiveSignal/ReceiveSignal.cs @@ -11,10 +11,10 @@ namespace Elsa.Activities.Signaling /// /// Suspends workflow execution until the specified signal is received. /// - [ActivityDefinition( + [Trigger( Category = "Workflows", - Description = "Halt workflow execution until the specified signal is received.", - Icon = "fas fa-traffic-light" + Description = "Suspend workflow execution until the specified signal is received.", + Outcomes = new[] { OutcomeNames.Done } )] public class ReceiveSignal : Activity { @@ -25,7 +25,7 @@ namespace Elsa.Activities.Signaling { if (context.Input is Signal triggeredSignal) return string.Equals(triggeredSignal.SignalName, Signal, StringComparison.OrdinalIgnoreCase); - + return false; } diff --git a/src/core/Elsa.Core/Activities/Signaling/TriggerSignal/SendSignal.cs b/src/core/Elsa.Core/Activities/Signaling/TriggerSignal/SendSignal.cs index 977cd05e4..2e43854fa 100644 --- a/src/core/Elsa.Core/Activities/Signaling/TriggerSignal/SendSignal.cs +++ b/src/core/Elsa.Core/Activities/Signaling/TriggerSignal/SendSignal.cs @@ -12,10 +12,10 @@ namespace Elsa.Activities.Signaling /// /// Triggers the specified signal. /// - [ActivityDefinition( + [Action( Category = "Workflows", Description = "Sends the specified signal.", - Icon = "fas fa-broadcast-tower" + Outcomes = new[] { OutcomeNames.Done } )] public class SendSignal : Activity { diff --git a/src/core/Elsa.Core/Activities/Workflows/RunWorkflow/RunWorkflow.cs b/src/core/Elsa.Core/Activities/Workflows/RunWorkflow/RunWorkflow.cs index fe29fded8..1b4af0ac4 100644 --- a/src/core/Elsa.Core/Activities/Workflows/RunWorkflow/RunWorkflow.cs +++ b/src/core/Elsa.Core/Activities/Workflows/RunWorkflow/RunWorkflow.cs @@ -11,7 +11,7 @@ using Open.Linq.AsyncExtensions; // ReSharper disable once CheckNamespace namespace Elsa.Activities.Workflows { - [ActivityDefinition( + [Activity( Category = "Workflows", Description = "Runs a child workflow." )] diff --git a/src/core/Elsa.Core/Metadata/ActivityDescriber.cs b/src/core/Elsa.Core/Metadata/ActivityDescriber.cs index cb4c09e0b..1a8267f65 100644 --- a/src/core/Elsa.Core/Metadata/ActivityDescriber.cs +++ b/src/core/Elsa.Core/Metadata/ActivityDescriber.cs @@ -21,18 +21,17 @@ namespace Elsa.Metadata public ActivityDescriptor Describe(Type activityType) { - var activityDefinitionAttribute = activityType.GetCustomAttribute(); - var typeName = activityDefinitionAttribute?.Type ?? activityType.Name; + var activityAttribute = activityType.GetCustomAttribute(); + var typeName = activityAttribute?.Type ?? activityType.Name; var displayName = - activityDefinitionAttribute?.DisplayName ?? + activityAttribute?.DisplayName ?? activityType.Name.Humanize(LetterCasing.Title); - var description = activityDefinitionAttribute?.Description; - var runtimeDescription = activityDefinitionAttribute?.RuntimeDescription; - var category = activityDefinitionAttribute?.Category ?? "Miscellaneous"; - var icon = activityDefinitionAttribute?.Icon; - var outcomes = activityDefinitionAttribute?.Outcomes ?? new[] { OutcomeNames.Done }; + var description = activityAttribute?.Description; + var category = activityAttribute?.Category ?? "Miscellaneous"; + var traits = activityAttribute?.Traits ?? ActivityTraits.Action; + var outcomes = activityAttribute?.Outcomes ?? new[] { OutcomeNames.Done }; var properties = DescribeProperties(activityType); return new ActivityDescriptor @@ -40,9 +39,8 @@ namespace Elsa.Metadata Type = typeName.Pascalize(), DisplayName = displayName, Description = description, - RuntimeDescription = runtimeDescription, Category = category, - Icon = icon, + Traits = traits, Properties = properties.ToArray(), Outcomes = outcomes }; diff --git a/src/dashboards/blazor/ElsaDashboard.Application.Server/Program.cs b/src/dashboards/blazor/ElsaDashboard.Application.Server/Program.cs index a50b1f038..bc2d0939f 100644 --- a/src/dashboards/blazor/ElsaDashboard.Application.Server/Program.cs +++ b/src/dashboards/blazor/ElsaDashboard.Application.Server/Program.cs @@ -6,7 +6,7 @@ namespace ElsaDashboard.Application.Server { public class Program { - public static bool UseBlazorServer = false; + public static bool UseBlazorServer = true; public static bool UseBlazorWebAssembly => !UseBlazorServer; public static RenderMode RenderMode => UseBlazorServer ? RenderMode.ServerPrerendered: RenderMode.WebAssemblyPrerendered; diff --git a/src/dashboards/blazor/ElsaDashboard.Application/Pages/Designer/ActivityPicker.razor b/src/dashboards/blazor/ElsaDashboard.Application/Pages/Designer/ActivityPicker.razor index e1f1f0f26..98ae49c00 100644 --- a/src/dashboards/blazor/ElsaDashboard.Application/Pages/Designer/ActivityPicker.razor +++ b/src/dashboards/blazor/ElsaDashboard.Application/Pages/Designer/ActivityPicker.razor @@ -9,26 +9,20 @@ - +
diff --git a/src/dashboards/blazor/ElsaDashboard.Application/Pages/Designer/ActivityPicker.razor.cs b/src/dashboards/blazor/ElsaDashboard.Application/Pages/Designer/ActivityPicker.razor.cs index b023a9fc6..050d9516c 100644 --- a/src/dashboards/blazor/ElsaDashboard.Application/Pages/Designer/ActivityPicker.razor.cs +++ b/src/dashboards/blazor/ElsaDashboard.Application/Pages/Designer/ActivityPicker.razor.cs @@ -1,21 +1,61 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Elsa.Client.Models; using ElsaDashboard.Shared.Rpc; using Microsoft.AspNetCore.Components; +using Microsoft.AspNetCore.Components.Web; namespace ElsaDashboard.Application.Pages.Designer { partial class ActivityPicker { [Inject] private IActivityService ActivityService { get; set; } = default!; - private ICollection> ActivityGroupings { get; set; } = new System.Collections.Generic.List>(); + private ActivityTraitFilter SelectedActivityTraitFilter { get; set; } + private string? ActivitySearchText { get; set; } + private ICollection ActivityTraitFilters => new[] { ActivityTraitFilter.All, ActivityTraitFilter.Actions, ActivityTraitFilter.Triggers }; + private ICollection Activities { get; set; } = new System.Collections.Generic.List(); + + private ICollection> ActivityGroupings => + FilterBySearchText( + FilterByTrait(Activities, SelectedActivityTraitFilter), + ActivitySearchText) + .GroupBy(x => x.Category) + .ToList(); protected override async Task OnInitializedAsync() { 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 FilterByTrait(IEnumerable 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 FilterBySearchText(IEnumerable 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; } } } \ No newline at end of file diff --git a/src/dashboards/blazor/ElsaDashboard.Application/Pages/Designer/ActivityTraitFilter.cs b/src/dashboards/blazor/ElsaDashboard.Application/Pages/Designer/ActivityTraitFilter.cs new file mode 100644 index 000000000..df04cdb87 --- /dev/null +++ b/src/dashboards/blazor/ElsaDashboard.Application/Pages/Designer/ActivityTraitFilter.cs @@ -0,0 +1,9 @@ +namespace ElsaDashboard.Application.Pages.Designer +{ + public enum ActivityTraitFilter + { + All, + Actions, + Triggers + } +} \ No newline at end of file