From 3ec9df87c1ea22a5112ea592df45eeadf4676906 Mon Sep 17 00:00:00 2001 From: Sipke Schoorstra Date: Sat, 1 Apr 2023 16:15:35 +0200 Subject: [PATCH] Initial work on Elsa Client --- .../Elsa.AllInOne.Web/Pages/Index.cshtml | 14 ++- .../Pages/_ViewImports.cshtml | 6 +- .../Elsa.Api.Client/Contracts/IElsaClient.cs | 7 +- .../Contracts/IWorkflowDefinitionsApi.cs | 17 +++ .../Contracts/IWorkflowInstancesApi.cs | 8 ++ .../DependencyInjectionExtensions.cs | 16 ++- src/clients/Elsa.Api.Client/IsExternalInit.cs | 8 ++ .../Models/DeleteWorkflowDefinitionRequest.cs | 12 ++ .../DeleteWorkflowDefinitionResponse.cs | 8 ++ .../Models/GetWorkflowDefinitionRequest.cs | 7 ++ .../Models/GetWorkflowDefinitionResponse.cs | 4 + .../Models/ListWorkflowDefinitionsRequest.cs | 34 ++++++ .../Models/ListWorkflowDefinitionsResponse.cs | 8 ++ .../Elsa.Api.Client/Models/VersionOptions.cs | 106 ++++++++++++++++++ .../Models/WorkflowDefinitionSummary.cs | 9 ++ .../Elsa.Api.Client/Services/ElsaClient.cs | 9 +- .../elsa-workflows-designer/src/index.html | 10 +- .../WorkflowDefinitions/List/Endpoint.cs | 2 + .../Elsa.Workflows.Designer.csproj | 4 - .../Elsa.Workflows.Designer/package-lock.json | 8 +- .../Models/WorkflowDefinitionSummary.cs | 8 ++ 21 files changed, 276 insertions(+), 29 deletions(-) create mode 100644 src/clients/Elsa.Api.Client/Contracts/IWorkflowInstancesApi.cs create mode 100644 src/clients/Elsa.Api.Client/IsExternalInit.cs create mode 100644 src/clients/Elsa.Api.Client/Models/DeleteWorkflowDefinitionRequest.cs create mode 100644 src/clients/Elsa.Api.Client/Models/DeleteWorkflowDefinitionResponse.cs create mode 100644 src/clients/Elsa.Api.Client/Models/GetWorkflowDefinitionRequest.cs create mode 100644 src/clients/Elsa.Api.Client/Models/GetWorkflowDefinitionResponse.cs create mode 100644 src/clients/Elsa.Api.Client/Models/ListWorkflowDefinitionsRequest.cs create mode 100644 src/clients/Elsa.Api.Client/Models/ListWorkflowDefinitionsResponse.cs create mode 100644 src/clients/Elsa.Api.Client/Models/VersionOptions.cs create mode 100644 src/clients/Elsa.Api.Client/Models/WorkflowDefinitionSummary.cs diff --git a/src/bundles/Elsa.AllInOne.Web/Pages/Index.cshtml b/src/bundles/Elsa.AllInOne.Web/Pages/Index.cshtml index 2cd984c2e..f77aacf4e 100644 --- a/src/bundles/Elsa.AllInOne.Web/Pages/Index.cshtml +++ b/src/bundles/Elsa.AllInOne.Web/Pages/Index.cshtml @@ -18,12 +18,14 @@ - -
- - - -
+ + +
+ + + +
+
\ No newline at end of file diff --git a/src/bundles/Elsa.AllInOne.Web/Pages/_ViewImports.cshtml b/src/bundles/Elsa.AllInOne.Web/Pages/_ViewImports.cshtml index 76466a876..9b1c88a64 100644 --- a/src/bundles/Elsa.AllInOne.Web/Pages/_ViewImports.cshtml +++ b/src/bundles/Elsa.AllInOne.Web/Pages/_ViewImports.cshtml @@ -1,2 +1,4 @@ -@namespace Elsa.AllInOne.Web.Pages -@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers \ No newline at end of file +@using Esprima.Ast +@namespace Elsa.AllInOne.Web.Pages +@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers +@using Elsa.Workflows.Designer \ No newline at end of file diff --git a/src/clients/Elsa.Api.Client/Contracts/IElsaClient.cs b/src/clients/Elsa.Api.Client/Contracts/IElsaClient.cs index fea4e613c..1a896543a 100644 --- a/src/clients/Elsa.Api.Client/Contracts/IElsaClient.cs +++ b/src/clients/Elsa.Api.Client/Contracts/IElsaClient.cs @@ -1,7 +1,7 @@ namespace Elsa.Api.Client.Contracts; /// -/// Represents a client for the Elsa API. +/// Represents a client for the Elsa API. Each API is exposed as a property. /// public interface IElsaClient { @@ -9,4 +9,9 @@ public interface IElsaClient /// Gets the workflow definitions API. /// IWorkflowDefinitionsApi WorkflowDefinitions { get; } + + /// + /// Gets the workflow instances API. + /// + IWorkflowInstancesApi WorkflowInstances { get; } } \ No newline at end of file diff --git a/src/clients/Elsa.Api.Client/Contracts/IWorkflowDefinitionsApi.cs b/src/clients/Elsa.Api.Client/Contracts/IWorkflowDefinitionsApi.cs index f7a5ec4fd..bbb490122 100644 --- a/src/clients/Elsa.Api.Client/Contracts/IWorkflowDefinitionsApi.cs +++ b/src/clients/Elsa.Api.Client/Contracts/IWorkflowDefinitionsApi.cs @@ -1,3 +1,5 @@ +using Elsa.Api.Client.Models; + namespace Elsa.Api.Client.Contracts; /// @@ -5,4 +7,19 @@ namespace Elsa.Api.Client.Contracts; /// public interface IWorkflowDefinitionsApi { + /// + /// Lists workflow definitions. + /// + /// The request containing options for listing workflow definitions. + /// The cancellation token. + /// The response containing the workflow definitions. + Task ListAsync(ListWorkflowDefinitionsRequest request, CancellationToken cancellationToken = default); + + /// + /// Deletes a workflow definition. + /// + /// The request containing the ID of the workflow definition to delete. + /// The cancellation token. + /// The response. + Task DeleteAsync(DeleteWorkflowDefinitionRequest request, CancellationToken cancellationToken = default); } \ No newline at end of file diff --git a/src/clients/Elsa.Api.Client/Contracts/IWorkflowInstancesApi.cs b/src/clients/Elsa.Api.Client/Contracts/IWorkflowInstancesApi.cs new file mode 100644 index 000000000..19af883b1 --- /dev/null +++ b/src/clients/Elsa.Api.Client/Contracts/IWorkflowInstancesApi.cs @@ -0,0 +1,8 @@ +namespace Elsa.Api.Client.Contracts; + +/// +/// Represents a client for the workflow instances API. +/// +public interface IWorkflowInstancesApi +{ +} \ No newline at end of file diff --git a/src/clients/Elsa.Api.Client/Extensions/DependencyInjectionExtensions.cs b/src/clients/Elsa.Api.Client/Extensions/DependencyInjectionExtensions.cs index 0e54f2509..95b3f4725 100644 --- a/src/clients/Elsa.Api.Client/Extensions/DependencyInjectionExtensions.cs +++ b/src/clients/Elsa.Api.Client/Extensions/DependencyInjectionExtensions.cs @@ -1,6 +1,7 @@ using Elsa.Api.Client.Contracts; using Elsa.Api.Client.Options; using Elsa.Api.Client.Services; +using JetBrains.Annotations; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Options; using Refit; @@ -10,6 +11,7 @@ namespace Elsa.Api.Client.Extensions; /// /// Provides extension methods for dependency injection. /// +[PublicAPI] public static class DependencyInjectionExtensions { /// @@ -21,16 +23,22 @@ public static class DependencyInjectionExtensions services.AddSingleton(); var settings = new RefitSettings(); - services.AddClient(settings); + services.AddElsaApiClient(settings); return services; } - private static void AddClient(this IServiceCollection services, RefitSettings settings) where T : class + /// + /// Adds a refit client for the specified API type. + /// + /// The service collection. + /// The refit settings. + /// The API type. + public static void AddElsaApiClient(this IServiceCollection services, RefitSettings settings) where T : class { - services.AddRefitClient(settings).ConfigureHttpClient(ConfigureHttpClient); + services.AddRefitClient(settings).ConfigureHttpClient(ConfigureElsaApiHttpClient); } - private static void ConfigureHttpClient(IServiceProvider serviceProvider, HttpClient httpClient) + private static void ConfigureElsaApiHttpClient(IServiceProvider serviceProvider, HttpClient httpClient) { var options = serviceProvider.GetRequiredService>().Value; httpClient.BaseAddress = options.BaseAddress; diff --git a/src/clients/Elsa.Api.Client/IsExternalInit.cs b/src/clients/Elsa.Api.Client/IsExternalInit.cs new file mode 100644 index 000000000..5b875183f --- /dev/null +++ b/src/clients/Elsa.Api.Client/IsExternalInit.cs @@ -0,0 +1,8 @@ +using System.ComponentModel; + +// ReSharper disable once CheckNamespace +namespace System.Runtime.CompilerServices +{ + [EditorBrowsable(EditorBrowsableState.Never)] + internal class IsExternalInit{} +} \ No newline at end of file diff --git a/src/clients/Elsa.Api.Client/Models/DeleteWorkflowDefinitionRequest.cs b/src/clients/Elsa.Api.Client/Models/DeleteWorkflowDefinitionRequest.cs new file mode 100644 index 000000000..19c7beade --- /dev/null +++ b/src/clients/Elsa.Api.Client/Models/DeleteWorkflowDefinitionRequest.cs @@ -0,0 +1,12 @@ +namespace Elsa.Api.Client.Contracts; + +/// +/// The request for deleting a workflow definition. +/// +public class DeleteWorkflowDefinitionRequest +{ + /// + /// The ID of the workflow definition to delete. + /// + public string DefinitionId { get; set; } +} \ No newline at end of file diff --git a/src/clients/Elsa.Api.Client/Models/DeleteWorkflowDefinitionResponse.cs b/src/clients/Elsa.Api.Client/Models/DeleteWorkflowDefinitionResponse.cs new file mode 100644 index 000000000..b149e4510 --- /dev/null +++ b/src/clients/Elsa.Api.Client/Models/DeleteWorkflowDefinitionResponse.cs @@ -0,0 +1,8 @@ +namespace Elsa.Api.Client.Contracts; + +/// +/// The response of deleting a workflow definition. +/// +public record DeleteWorkflowDefinitionResponse +{ +} \ No newline at end of file diff --git a/src/clients/Elsa.Api.Client/Models/GetWorkflowDefinitionRequest.cs b/src/clients/Elsa.Api.Client/Models/GetWorkflowDefinitionRequest.cs new file mode 100644 index 000000000..c77ad1e03 --- /dev/null +++ b/src/clients/Elsa.Api.Client/Models/GetWorkflowDefinitionRequest.cs @@ -0,0 +1,7 @@ +namespace Elsa.Api.Client.Contracts; + +public class GetWorkflowDefinitionRequest +{ + public string DefinitionId { get; set; } = default!; + public string? VersionOptions { get; set; } +} \ No newline at end of file diff --git a/src/clients/Elsa.Api.Client/Models/GetWorkflowDefinitionResponse.cs b/src/clients/Elsa.Api.Client/Models/GetWorkflowDefinitionResponse.cs new file mode 100644 index 000000000..993443a2f --- /dev/null +++ b/src/clients/Elsa.Api.Client/Models/GetWorkflowDefinitionResponse.cs @@ -0,0 +1,4 @@ +namespace Elsa.Api.Client.Contracts; + +public record GetWorkflowDefinitionResponse( + ); \ No newline at end of file diff --git a/src/clients/Elsa.Api.Client/Models/ListWorkflowDefinitionsRequest.cs b/src/clients/Elsa.Api.Client/Models/ListWorkflowDefinitionsRequest.cs new file mode 100644 index 000000000..995153f8b --- /dev/null +++ b/src/clients/Elsa.Api.Client/Models/ListWorkflowDefinitionsRequest.cs @@ -0,0 +1,34 @@ +using Refit; + +namespace Elsa.Api.Client.Models; + +/// +/// Represents a request to list workflow definitions. +/// +public class ListWorkflowDefinitionsRequest +{ + /// + /// The page number. + /// + public int? Page { get; set; } + + /// + /// The page size. + /// + public int? PageSize { get; set; } + + /// + /// The version options. + /// + public VersionOptions? Version { get; set; } + + /// + /// The name of the workflow materializer to filter by. + /// + [AliasAs("materializer")] public string? MaterializerName { get; set; } + + /// + /// The labels to filter by. + /// + [AliasAs("label")] public string[]? Labels { get; set; } +} \ No newline at end of file diff --git a/src/clients/Elsa.Api.Client/Models/ListWorkflowDefinitionsResponse.cs b/src/clients/Elsa.Api.Client/Models/ListWorkflowDefinitionsResponse.cs new file mode 100644 index 000000000..92257a2f9 --- /dev/null +++ b/src/clients/Elsa.Api.Client/Models/ListWorkflowDefinitionsResponse.cs @@ -0,0 +1,8 @@ +namespace Elsa.Api.Client.Models; + +/// +/// Represents a response from listing workflow definitions. +/// +/// The workflow definitions. +/// The total number of workflow definitions. +public record ListWorkflowDefinitionsResponse(ICollection Items, int TotalCount); \ No newline at end of file diff --git a/src/clients/Elsa.Api.Client/Models/VersionOptions.cs b/src/clients/Elsa.Api.Client/Models/VersionOptions.cs new file mode 100644 index 000000000..39d8946dc --- /dev/null +++ b/src/clients/Elsa.Api.Client/Models/VersionOptions.cs @@ -0,0 +1,106 @@ +using JetBrains.Annotations; + +namespace Elsa.Api.Client.Models; + +/// +/// Represents the version to get. +/// +[PublicAPI] +public struct VersionOptions +{ + /// + /// Gets the latest version. + /// + public static readonly VersionOptions Latest = new() { IsLatest = true }; + + /// + /// Gets the published version. + /// + public static readonly VersionOptions Published = new() { IsPublished = true }; + + /// + /// Gets the published version if available, and if not, the latest version. + /// + public static readonly VersionOptions LatestOrPublished = new() { IsLatestOrPublished = true }; + + /// + /// Gets the latest, published version. + /// + public static readonly VersionOptions LatestAndPublished = new() { IsLatestOrPublished = true }; + + /// + /// Gets the draft version. + /// + public static readonly VersionOptions Draft = new() { IsDraft = true }; + + /// + /// Gets all versions. + /// + public static readonly VersionOptions All = new() { AllVersions = true }; + + /// + /// Gets a specific version. + /// + public static VersionOptions SpecificVersion(int version) => new() { Version = version }; + + /// + /// Parses a string into a . + /// + public static VersionOptions FromString(string value) => + value switch + { + "AllVersions" => All, + "Draft" => Draft, + "Latest" => Latest, + "Published" => Published, + "LatestOrPublished" => LatestOrPublished, + "LatestAndPublished" => LatestAndPublished, + _ => SpecificVersion(int.Parse(value)) + }; + + public static bool TryParse(string value, out VersionOptions versionOptions) + { + versionOptions = FromString(value); + return true; + } + + /// + /// Gets the latest version. + /// + public bool IsLatest { get; private set; } + + /// + /// Gets the published version if available, and if not, the latest version. + /// + public bool IsLatestOrPublished { get; private set; } + + /// + /// Gets the latest, published version. + /// + public bool IsLatestAndPublished { get; private set; } + + /// + /// Gets the published version. + /// + public bool IsPublished { get; private set; } + + /// + /// Gets the draft version. + /// + public bool IsDraft { get; private set; } + + /// + /// Gets all versions. + /// + public bool AllVersions { get; private set; } + + /// + /// Gets a specific version. + /// + public int Version { get; private set; } + + /// + /// Returns a simple string representation of this . + /// + public override string ToString() => AllVersions ? "AllVersions" : IsDraft ? "Draft" : IsLatest ? "Latest" : IsPublished ? "Published" : IsLatestOrPublished ? "LatestOrPublished" : IsLatestAndPublished ? "LatestAndPublished" : Version.ToString(); +} \ No newline at end of file diff --git a/src/clients/Elsa.Api.Client/Models/WorkflowDefinitionSummary.cs b/src/clients/Elsa.Api.Client/Models/WorkflowDefinitionSummary.cs new file mode 100644 index 000000000..c1ca5ee6a --- /dev/null +++ b/src/clients/Elsa.Api.Client/Models/WorkflowDefinitionSummary.cs @@ -0,0 +1,9 @@ +using JetBrains.Annotations; + +namespace Elsa.Api.Client.Models; + +/// +/// A summary of a workflow definition. +/// +[PublicAPI] +public record WorkflowDefinitionSummary(string Id, string DefinitionId, string? Name, string? Description, int? Version, bool IsLatest, bool IsPublished, string MaterializerName, DateTimeOffset CreatedAt); \ 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 38674f82c..60b2767f6 100644 --- a/src/clients/Elsa.Api.Client/Services/ElsaClient.cs +++ b/src/clients/Elsa.Api.Client/Services/ElsaClient.cs @@ -8,12 +8,15 @@ public class ElsaClient : IElsaClient /// /// Initializes a new instance of the class. /// - /// The workflow definitions API. - public ElsaClient(IWorkflowDefinitionsApi workflowDefinitionsApi) + public ElsaClient(IWorkflowDefinitionsApi workflowDefinitions, IWorkflowInstancesApi workflowInstances) { - WorkflowDefinitions = workflowDefinitionsApi; + WorkflowDefinitions = workflowDefinitions; + WorkflowInstances = workflowInstances; } /// public IWorkflowDefinitionsApi WorkflowDefinitions { get; } + + /// + public IWorkflowInstancesApi WorkflowInstances { get; } } \ No newline at end of file diff --git a/src/designer/designer_packages/elsa-workflows-designer/src/index.html b/src/designer/designer_packages/elsa-workflows-designer/src/index.html index 982e8d79c..a2ad3c674 100644 --- a/src/designer/designer_packages/elsa-workflows-designer/src/index.html +++ b/src/designer/designer_packages/elsa-workflows-designer/src/index.html @@ -13,11 +13,11 @@ - -
- - -
+ +
+ + +