diff --git a/src/clients/Elsa.Api.Client/Contracts/IElsaClient.cs b/src/clients/Elsa.Api.Client/Contracts/IElsaClient.cs
index 16f3a2506..e255ff9c6 100644
--- a/src/clients/Elsa.Api.Client/Contracts/IElsaClient.cs
+++ b/src/clients/Elsa.Api.Client/Contracts/IElsaClient.cs
@@ -1,4 +1,5 @@
-using Elsa.Api.Client.Resources.WorkflowDefinitions.Contracts;
+using Elsa.Api.Client.Resources.ActivityDescriptors.Contracts;
+using Elsa.Api.Client.Resources.WorkflowDefinitions.Contracts;
using Elsa.Api.Client.Resources.WorkflowInstances.Contracts;
namespace Elsa.Api.Client.Contracts;
@@ -13,6 +14,11 @@ public interface IElsaClient
///
IWorkflowDefinitionsApi WorkflowDefinitions { get; }
+ ///
+ /// Gets the activity descriptors API.
+ ///
+ IActivityDescriptorsApi ActivityDescriptors { get; }
+
///
/// Gets the workflow instances API.
///
diff --git a/src/clients/Elsa.Api.Client/Extensions/DependencyInjectionExtensions.cs b/src/clients/Elsa.Api.Client/Extensions/DependencyInjectionExtensions.cs
index 862de56f2..c63eb81a8 100644
--- a/src/clients/Elsa.Api.Client/Extensions/DependencyInjectionExtensions.cs
+++ b/src/clients/Elsa.Api.Client/Extensions/DependencyInjectionExtensions.cs
@@ -1,5 +1,6 @@
using Elsa.Api.Client.Contracts;
using Elsa.Api.Client.Options;
+using Elsa.Api.Client.Resources.ActivityDescriptors.Contracts;
using Elsa.Api.Client.Resources.Identity.Contracts;
using Elsa.Api.Client.Resources.WorkflowDefinitions.Contracts;
using Elsa.Api.Client.Services;
@@ -26,6 +27,7 @@ public static class DependencyInjectionExtensions
var settings = new RefitSettings();
services.AddElsaApiClient(settings);
+ services.AddElsaApiClient(settings);
services.AddElsaApiClient(settings);
return services;
}
diff --git a/src/clients/Elsa.Api.Client/Resources/ActivityDescriptors/Contracts/IWorkflowDefinitionsApi.cs b/src/clients/Elsa.Api.Client/Resources/ActivityDescriptors/Contracts/IWorkflowDefinitionsApi.cs
new file mode 100644
index 000000000..f7dded57b
--- /dev/null
+++ b/src/clients/Elsa.Api.Client/Resources/ActivityDescriptors/Contracts/IWorkflowDefinitionsApi.cs
@@ -0,0 +1,19 @@
+using Elsa.Api.Client.Resources.ActivityDescriptors.Models;
+using Refit;
+
+namespace Elsa.Api.Client.Resources.ActivityDescriptors.Contracts;
+
+///
+/// Represents a client for the workflow definitions API.
+///
+public interface IActivityDescriptorsApi
+{
+ ///
+ /// Lists activity descriptors.
+ ///
+ /// The request containing options for listing activity descriptors.
+ /// The cancellation token.
+ /// The response containing the activity descriptors.
+ [Get("/descriptors/activities")]
+ Task ListAsync([Query]ListActivityDescriptorsRequest request, CancellationToken cancellationToken = default);
+}
\ No newline at end of file
diff --git a/src/clients/Elsa.Api.Client/Resources/ActivityDescriptors/Models/ActivityDescriptor.cs b/src/clients/Elsa.Api.Client/Resources/ActivityDescriptors/Models/ActivityDescriptor.cs
new file mode 100644
index 000000000..adcb69983
--- /dev/null
+++ b/src/clients/Elsa.Api.Client/Resources/ActivityDescriptors/Models/ActivityDescriptor.cs
@@ -0,0 +1,77 @@
+namespace Elsa.Api.Client.Resources.ActivityDescriptors.Models;
+
+///
+/// A descriptor of an activity type.
+///
+public record ActivityDescriptor
+{
+ ///
+ /// The fully qualified name of the activity type.
+ ///
+ public string TypeName { get; init; } = default!;
+
+ ///
+ /// The namespace of the activity type.
+ ///
+ public string Namespace { get; init; } = default!;
+
+ ///
+ /// The name of the activity type.
+ ///
+ public string Name { get; init; } = default!;
+
+ ///
+ /// The version of the activity type.
+ ///
+ public int Version { get; init; }
+
+ ///
+ /// The category of the activity type.
+ ///
+ public string Category { get; init; } = default!;
+
+ ///
+ /// The display name of the activity type.
+ ///
+ public string? DisplayName { get; init; }
+
+ ///
+ /// The description of the activity type.
+ ///
+ public string? Description { get; init; }
+
+ ///
+ /// The input properties of the activity type.
+ ///
+ public ICollection Inputs { get; init; } = new List();
+
+ ///
+ /// The output properties of the activity type.
+ ///
+ public ICollection Outputs { get; init; } = new List();
+
+ ///
+ /// The kind of activity.
+ ///
+ public ActivityKind Kind { get; set; } = ActivityKind.Action;
+
+ ///
+ /// The ports of the activity type.
+ ///
+ public ICollection Ports { get; init; } = new List();
+
+ ///
+ /// The custom properties of the activity type.
+ ///
+ public IDictionary CustomProperties { get; set; } = new Dictionary();
+
+ ///
+ /// A value indicating whether this activity is a container of child activities.
+ ///
+ public bool IsContainer { get; set; }
+
+ ///
+ /// Whether this activity type is selectable from activity pickers.
+ ///
+ public bool IsBrowsable { get; set; }
+}
\ No newline at end of file
diff --git a/src/clients/Elsa.Api.Client/Resources/ActivityDescriptors/Models/ActivityKind.cs b/src/clients/Elsa.Api.Client/Resources/ActivityDescriptors/Models/ActivityKind.cs
new file mode 100644
index 000000000..1049d01c3
--- /dev/null
+++ b/src/clients/Elsa.Api.Client/Resources/ActivityDescriptors/Models/ActivityKind.cs
@@ -0,0 +1,27 @@
+namespace Elsa.Api.Client.Resources.ActivityDescriptors.Models;
+
+///
+/// Represents the kind of an activity, which affects how it is executed.
+///
+public enum ActivityKind
+{
+ ///
+ /// Always run synchronously.
+ ///
+ Action,
+
+ ///
+ /// Can be used to trigger new workflows.
+ ///
+ Trigger,
+
+ ///
+ /// Always run asynchronously.
+ ///
+ Job,
+
+ ///
+ /// Run synchronously by default (like , but can be configured to run asynchronously (like ).
+ ///
+ Task
+}
\ No newline at end of file
diff --git a/src/clients/Elsa.Api.Client/Resources/ActivityDescriptors/Models/InputDescriptor.cs b/src/clients/Elsa.Api.Client/Resources/ActivityDescriptors/Models/InputDescriptor.cs
new file mode 100644
index 000000000..1d784ec73
--- /dev/null
+++ b/src/clients/Elsa.Api.Client/Resources/ActivityDescriptors/Models/InputDescriptor.cs
@@ -0,0 +1,57 @@
+using JetBrains.Annotations;
+
+namespace Elsa.Api.Client.Resources.ActivityDescriptors.Models;
+
+///
+/// A descriptor of an activity's input property.
+///
+[PublicAPI]
+public class InputDescriptor : PropertyDescriptor
+{
+ ///
+ public InputDescriptor()
+ {
+ }
+
+ ///
+ /// True if the property is wrapped with an "Input{T}" type, false otherwise.
+ ///
+ public bool IsWrapped { get; set; }
+
+ ///
+ /// A string value that hints at what UI control might be used to render in a UI tool.
+ ///
+ public string UIHint { get; set; } = default!;
+
+ ///
+ /// An arbitrary options object that can be used by some UI tool.
+ ///
+ public object? Options { get; set; }
+
+ ///
+ /// The category to whcih this input belongs. Can be used by UI to e.g. render different inputs in different tabs.
+ ///
+ public string? Category { get; set; }
+
+ ///
+ /// The default value.
+ ///
+ public object? DefaultValue { get; set; }
+
+ ///
+ /// The default syntax.
+ ///
+ public string? DefaultSyntax { get; set; }
+ //public ICollection SupportedSyntaxes { get; set; } = new List();
+
+ ///
+ /// True if the input is readonly, false otherwise.
+ ///
+ public bool? IsReadOnly { get; set; }
+
+ ///
+ /// The storage driver type to use for persistence.
+ /// If no driver is specified, the referenced memory block will remain in memory for as long as the expression execution context exists.
+ ///
+ public string? StorageDriverType { get; set; }
+}
\ No newline at end of file
diff --git a/src/clients/Elsa.Api.Client/Resources/ActivityDescriptors/Models/ListActivityDescriptorsRequest.cs b/src/clients/Elsa.Api.Client/Resources/ActivityDescriptors/Models/ListActivityDescriptorsRequest.cs
new file mode 100644
index 000000000..9ec5c43fc
--- /dev/null
+++ b/src/clients/Elsa.Api.Client/Resources/ActivityDescriptors/Models/ListActivityDescriptorsRequest.cs
@@ -0,0 +1,6 @@
+namespace Elsa.Api.Client.Resources.ActivityDescriptors.Models;
+
+///
+/// Represents a request to list activity descriptors.
+///
+public record ListActivityDescriptorsRequest;
\ No newline at end of file
diff --git a/src/clients/Elsa.Api.Client/Resources/ActivityDescriptors/Models/ListActivityDescriptorsResponse.cs b/src/clients/Elsa.Api.Client/Resources/ActivityDescriptors/Models/ListActivityDescriptorsResponse.cs
new file mode 100644
index 000000000..cc9073541
--- /dev/null
+++ b/src/clients/Elsa.Api.Client/Resources/ActivityDescriptors/Models/ListActivityDescriptorsResponse.cs
@@ -0,0 +1,8 @@
+namespace Elsa.Api.Client.Resources.ActivityDescriptors.Models;
+
+///
+/// Represents a response from listing activity descriptors.
+///
+/// The activity descriptors.
+/// The total number of activity descriptors.
+public record ListActivityDescriptorsResponse(ICollection Items, int Count);
\ No newline at end of file
diff --git a/src/clients/Elsa.Api.Client/Resources/ActivityDescriptors/Models/OutputDescriptor.cs b/src/clients/Elsa.Api.Client/Resources/ActivityDescriptors/Models/OutputDescriptor.cs
new file mode 100644
index 000000000..390296870
--- /dev/null
+++ b/src/clients/Elsa.Api.Client/Resources/ActivityDescriptors/Models/OutputDescriptor.cs
@@ -0,0 +1,11 @@
+using JetBrains.Annotations;
+
+namespace Elsa.Api.Client.Resources.ActivityDescriptors.Models;
+
+///
+/// A descriptor of an activity's output property.
+///
+[PublicAPI]
+public class OutputDescriptor : PropertyDescriptor
+{
+}
\ No newline at end of file
diff --git a/src/clients/Elsa.Api.Client/Resources/ActivityDescriptors/Models/Port.cs b/src/clients/Elsa.Api.Client/Resources/ActivityDescriptors/Models/Port.cs
new file mode 100644
index 000000000..953df1d2d
--- /dev/null
+++ b/src/clients/Elsa.Api.Client/Resources/ActivityDescriptors/Models/Port.cs
@@ -0,0 +1,27 @@
+namespace Elsa.Api.Client.Resources.ActivityDescriptors.Models;
+
+///
+/// Represents a port on an activity.
+///
+public class Port
+{
+ ///
+ /// Gets or sets the name of the port.
+ ///
+ public string Name { get; set; } = default!;
+
+ ///
+ /// Gets or sets the display name of the port.
+ ///
+ public string? DisplayName { get; set; }
+
+ ///
+ /// Gets or sets the type of the port.
+ ///
+ public PortType Type { get; set; }
+
+ ///
+ /// Gets or sets the visibility of the port.
+ ///
+ public bool IsBrowsable { get; set; } = true;
+}
\ No newline at end of file
diff --git a/src/clients/Elsa.Api.Client/Resources/ActivityDescriptors/Models/PortType.cs b/src/clients/Elsa.Api.Client/Resources/ActivityDescriptors/Models/PortType.cs
new file mode 100644
index 000000000..673ede776
--- /dev/null
+++ b/src/clients/Elsa.Api.Client/Resources/ActivityDescriptors/Models/PortType.cs
@@ -0,0 +1,17 @@
+namespace Elsa.Api.Client.Resources.ActivityDescriptors.Models;
+
+///
+/// The type of a port.
+///
+public enum PortType
+{
+ ///
+ /// A port that is embedded in the activity.
+ ///
+ Embedded,
+
+ ///
+ /// A flow port.
+ ///
+ Flow
+}
\ No newline at end of file
diff --git a/src/clients/Elsa.Api.Client/Resources/ActivityDescriptors/Models/PropertyDescriptor.cs b/src/clients/Elsa.Api.Client/Resources/ActivityDescriptors/Models/PropertyDescriptor.cs
new file mode 100644
index 000000000..927f0eaa2
--- /dev/null
+++ b/src/clients/Elsa.Api.Client/Resources/ActivityDescriptors/Models/PropertyDescriptor.cs
@@ -0,0 +1,47 @@
+using System.Text.Json.Serialization;
+using JetBrains.Annotations;
+
+namespace Elsa.Api.Client.Resources.ActivityDescriptors.Models;
+
+///
+/// A base type for and .
+///
+[PublicAPI]
+public abstract class PropertyDescriptor
+{
+ ///
+ /// The name.
+ ///
+ public string Name { get; set; } = default!;
+
+ ///
+ /// The .NET type.
+ ///
+ [JsonPropertyName("typeName")]
+ public string TypeName { get; set; } = default!;
+
+ ///
+ /// The user friendly name of the input. Used by UI tools.
+ ///
+ public string? DisplayName { get; set; }
+
+ ///
+ /// The user friendly description of the input. Used by UI tools.
+ ///
+ public string? Description { get; set; }
+
+ ///
+ /// The order in which this input should be displayed by UI tools.
+ ///
+ public float Order { get; set; }
+
+ ///
+ /// True if this input should be displayed by UI tools, false otherwise.
+ ///
+ public bool? IsBrowsable { get; set; }
+
+ ///
+ /// True if this input property is synthetic, which means it does not exist physically on the activity's .NET type.
+ ///
+ public bool IsSynthetic { get; set; }
+}
\ No newline at end of file
diff --git a/src/clients/Elsa.Api.Client/Services/ElsaClient.cs b/src/clients/Elsa.Api.Client/Services/ElsaClient.cs
index b46974121..562f75ec9 100644
--- a/src/clients/Elsa.Api.Client/Services/ElsaClient.cs
+++ b/src/clients/Elsa.Api.Client/Services/ElsaClient.cs
@@ -1,4 +1,5 @@
using Elsa.Api.Client.Contracts;
+using Elsa.Api.Client.Resources.ActivityDescriptors.Contracts;
using Elsa.Api.Client.Resources.WorkflowDefinitions.Contracts;
using Elsa.Api.Client.Resources.WorkflowInstances.Contracts;
@@ -10,15 +11,19 @@ public class ElsaClient : IElsaClient
///
/// Initializes a new instance of the class.
///
- public ElsaClient(IWorkflowDefinitionsApi workflowDefinitions, IWorkflowInstancesApi workflowInstances)
+ public ElsaClient(IWorkflowDefinitionsApi workflowDefinitions, IWorkflowInstancesApi workflowInstances, IActivityDescriptorsApi activityDescriptors)
{
WorkflowDefinitions = workflowDefinitions;
WorkflowInstances = workflowInstances;
+ ActivityDescriptors = activityDescriptors;
}
///
public IWorkflowDefinitionsApi WorkflowDefinitions { get; }
+ ///
+ public IActivityDescriptorsApi ActivityDescriptors { get; }
+
///
public IWorkflowInstancesApi WorkflowInstances { get; }
}
\ No newline at end of file
diff --git a/src/modules/Elsa.Workflows.Api/Endpoints/ActivityDescriptors/List/Models.cs b/src/modules/Elsa.Workflows.Api/Endpoints/ActivityDescriptors/List/Models.cs
index 0b5ebb1b4..2792d345a 100644
--- a/src/modules/Elsa.Workflows.Api/Endpoints/ActivityDescriptors/List/Models.cs
+++ b/src/modules/Elsa.Workflows.Api/Endpoints/ActivityDescriptors/List/Models.cs
@@ -12,4 +12,5 @@ internal class Response
}
public ICollection Items { get; set; }
+ public int Count => Items.Count;
}
\ No newline at end of file