From 460c75227dd1e56d2f77cb9447a2d29d11edf906 Mon Sep 17 00:00:00 2001 From: Sipke Schoorstra Date: Mon, 28 Dec 2020 17:34:44 +0100 Subject: [PATCH] Implement delete workflow definition --- .../Services/IWorkflowDefinitionsApi.cs | 3 + .../Events/ManyWorkflowInstancesDeleted.cs | 16 ++ .../Extensions/WorkflowBlueprintExtensions.cs | 11 +- .../Services/IWorkflowPublisher.cs | 14 +- src/core/Elsa.Core/Handlers/UpdateTriggers.cs | 20 +- .../EventPublishingWorkflowInstanceStore.cs | 15 +- ...rkflowDefinitionVersionIdsSpecification.cs | 15 ++ .../Elsa.Core/Services/WorkflowPublisher.cs | 21 ++- .../Pages/WorkflowDefinitions/List.razor | 124 ++----------- .../Pages/WorkflowDefinitions/List.razor.cs | 4 +- .../Pages/WorkflowRegistry/List.razor | 173 ++---------------- .../Rpc/WorkflowDefinitionService.cs | 1 + .../WorkflowDefinitionServiceExtensions.cs | 12 +- .../Models/DeleteWorkflowDefinitionRequest.cs | 19 ++ .../Services/IWorkflowDefinitionService.cs | 3 + .../Stores/YesSqlWorkflowDefinitionStore.cs | 9 +- .../Endpoints/WorkflowDefinitions/Delete.cs | 37 ++++ 17 files changed, 186 insertions(+), 311 deletions(-) create mode 100644 src/core/Elsa.Abstractions/Events/ManyWorkflowInstancesDeleted.cs create mode 100644 src/core/Elsa.Core/Persistence/Specifications/ManyWorkflowDefinitionVersionIdsSpecification.cs create mode 100644 src/dashboards/blazor/ElsaDashboard.Shared/Rpc/WorkflowDefinition/Models/DeleteWorkflowDefinitionRequest.cs create mode 100644 src/server/Elsa.Server.Api/Endpoints/WorkflowDefinitions/Delete.cs diff --git a/src/clients/Elsa.Client/Services/IWorkflowDefinitionsApi.cs b/src/clients/Elsa.Client/Services/IWorkflowDefinitionsApi.cs index c42306cc3..5341bd8d5 100644 --- a/src/clients/Elsa.Client/Services/IWorkflowDefinitionsApi.cs +++ b/src/clients/Elsa.Client/Services/IWorkflowDefinitionsApi.cs @@ -18,5 +18,8 @@ namespace Elsa.Client.Services [Post("/v1/workflow-definitions")] Task SaveAsync([Body] SaveWorkflowDefinitionRequest request, CancellationToken cancellationToken = default); + + [Delete("/v1/workflow-definitions/{workflowDefinitionId}")] + Task DeleteAsync(string workflowDefinitionId, CancellationToken cancellationToken = default); } } \ No newline at end of file diff --git a/src/core/Elsa.Abstractions/Events/ManyWorkflowInstancesDeleted.cs b/src/core/Elsa.Abstractions/Events/ManyWorkflowInstancesDeleted.cs new file mode 100644 index 000000000..db2ebf8de --- /dev/null +++ b/src/core/Elsa.Abstractions/Events/ManyWorkflowInstancesDeleted.cs @@ -0,0 +1,16 @@ +using System.Collections.Generic; +using Elsa.Models; +using MediatR; + +namespace Elsa.Events +{ + public class ManyWorkflowInstancesDeleted : INotification + { + public ManyWorkflowInstancesDeleted(IEnumerable workflowInstances) + { + WorkflowInstances = workflowInstances; + } + + public IEnumerable WorkflowInstances { get; } + } +} \ No newline at end of file diff --git a/src/core/Elsa.Abstractions/Extensions/WorkflowBlueprintExtensions.cs b/src/core/Elsa.Abstractions/Extensions/WorkflowBlueprintExtensions.cs index fa2ee670a..f8ad5167a 100644 --- a/src/core/Elsa.Abstractions/Extensions/WorkflowBlueprintExtensions.cs +++ b/src/core/Elsa.Abstractions/Extensions/WorkflowBlueprintExtensions.cs @@ -13,7 +13,7 @@ namespace Elsa { public static class WorkflowBlueprintExtensions { - public static ValueTask GetActivityPropertyValue( + public static ValueTask GetActivityPropertyValue( this IWorkflowBlueprint workflowBlueprint, string activityId, Expression> propertyExpression, @@ -25,15 +25,18 @@ namespace Elsa return GetActivityPropertyValue(workflowBlueprint, activityId, propertyName, activityExecutionContext, cancellationToken); } - public static async ValueTask GetActivityPropertyValue( + public static async ValueTask GetActivityPropertyValue( this IWorkflowBlueprint workflowBlueprint, string activityId, string propertyName, ActivityExecutionContext activityExecutionContext, CancellationToken cancellationToken) - => (T) await workflowBlueprint.GetActivityPropertyValue(activityId, propertyName, activityExecutionContext, cancellationToken); + { + var value = await workflowBlueprint.GetActivityPropertyValue(activityId, propertyName, activityExecutionContext, cancellationToken); + return value == null ? default : (T) value; + } - public static async ValueTask GetActivityPropertyValue( + public static async ValueTask GetActivityPropertyValue( this IWorkflowBlueprint workflowBlueprint, string activityId, string propertyName, diff --git a/src/core/Elsa.Abstractions/Services/IWorkflowPublisher.cs b/src/core/Elsa.Abstractions/Services/IWorkflowPublisher.cs index c2f9af6d2..d429829c9 100644 --- a/src/core/Elsa.Abstractions/Services/IWorkflowPublisher.cs +++ b/src/core/Elsa.Abstractions/Services/IWorkflowPublisher.cs @@ -7,17 +7,11 @@ namespace Elsa.Services public interface IWorkflowPublisher { WorkflowDefinition New(); - Task PublishAsync(string workflowDefinitionId, CancellationToken cancellationToken = default); - - Task PublishAsync( - WorkflowDefinition workflowDefinition, - CancellationToken cancellationToken = default); - + Task PublishAsync(WorkflowDefinition workflowDefinition, CancellationToken cancellationToken = default); Task GetDraftAsync(string workflowDefinitionId, CancellationToken cancellationToken= default); - - Task SaveDraftAsync( - WorkflowDefinition workflowDefinition, - CancellationToken cancellationToken = default); + Task SaveDraftAsync(WorkflowDefinition workflowDefinition, CancellationToken cancellationToken = default); + Task DeleteAsync(string workflowDefinitionId, CancellationToken cancellationToken = default); + Task DeleteAsync(WorkflowDefinition workflowDefinition, CancellationToken cancellationToken = default); } } \ No newline at end of file diff --git a/src/core/Elsa.Core/Handlers/UpdateTriggers.cs b/src/core/Elsa.Core/Handlers/UpdateTriggers.cs index 254945476..f7f8cf287 100644 --- a/src/core/Elsa.Core/Handlers/UpdateTriggers.cs +++ b/src/core/Elsa.Core/Handlers/UpdateTriggers.cs @@ -1,3 +1,4 @@ +using System.Linq; using System.Threading; using System.Threading.Tasks; using Elsa.Events; @@ -8,7 +9,7 @@ using MediatR; namespace Elsa.Handlers { - public class UpdateTriggers : INotificationHandler + public class UpdateTriggers : INotificationHandler, INotificationHandler { private readonly IWorkflowSelector _workflowSelector; private readonly IWorkflowRegistry _workflowRegistry; @@ -22,11 +23,22 @@ namespace Elsa.Handlers public async Task Handle(WorkflowInstanceSaved notification, CancellationToken cancellationToken) { var workflowInstance = notification.WorkflowInstance; - var workflowBlueprint = await _workflowRegistry.GetWorkflowAsync(workflowInstance.DefinitionId, workflowInstance.TenantId, VersionOptions.SpecificVersion(workflowInstance.Version), cancellationToken); - + await UpdateTriggersAsync(workflowInstance.DefinitionId, workflowInstance.TenantId, VersionOptions.SpecificVersion(workflowInstance.Version), cancellationToken); + } + + public async Task Handle(ManyWorkflowInstancesDeleted notification, CancellationToken cancellationToken) + { + var workflowInstance = notification.WorkflowInstances.First(); + await UpdateTriggersAsync(workflowInstance.DefinitionId, workflowInstance.TenantId, VersionOptions.Latest, cancellationToken); + } + + private async Task UpdateTriggersAsync(string workflowDefinitionId, string? tenantId, VersionOptions versionOptions, CancellationToken cancellationToken) + { + var workflowBlueprint = await _workflowRegistry.GetWorkflowAsync(workflowDefinitionId, tenantId, versionOptions, cancellationToken); + if (workflowBlueprint == null) return; - + await _workflowSelector.UpdateTriggersAsync(workflowBlueprint, cancellationToken); } } diff --git a/src/core/Elsa.Core/Persistence/Decorators/EventPublishingWorkflowInstanceStore.cs b/src/core/Elsa.Core/Persistence/Decorators/EventPublishingWorkflowInstanceStore.cs index 6bbecebab..662060120 100644 --- a/src/core/Elsa.Core/Persistence/Decorators/EventPublishingWorkflowInstanceStore.cs +++ b/src/core/Elsa.Core/Persistence/Decorators/EventPublishingWorkflowInstanceStore.cs @@ -1,10 +1,12 @@ using System.Collections.Generic; +using System.Linq; using System.Threading; using System.Threading.Tasks; using Elsa.Events; using Elsa.Models; using Elsa.Persistence.Specifications; using MediatR; +using Open.Linq.AsyncExtensions; namespace Elsa.Persistence.Decorators { @@ -18,7 +20,7 @@ namespace Elsa.Persistence.Decorators _store = store; _mediator = mediator; } - + public async Task SaveAsync(WorkflowInstance entity, CancellationToken cancellationToken = default) { await _store.SaveAsync(entity, cancellationToken); @@ -33,11 +35,16 @@ namespace Elsa.Persistence.Decorators public async Task DeleteManyAsync(ISpecification specification, CancellationToken cancellationToken = default) { - var instances = await FindManyAsync(specification, cancellationToken: cancellationToken); + var instances = await FindManyAsync(specification, cancellationToken: cancellationToken).ToList(); var count = await _store.DeleteManyAsync(specification, cancellationToken); - foreach (var instance in instances) - await _mediator.Publish(new WorkflowInstanceDeleted(instance), cancellationToken); + if (instances.Any()) + { + foreach (var instance in instances) + await _mediator.Publish(new WorkflowInstanceDeleted(instance), cancellationToken); + + await _mediator.Publish(new ManyWorkflowInstancesDeleted(instances), cancellationToken); + } return count; } diff --git a/src/core/Elsa.Core/Persistence/Specifications/ManyWorkflowDefinitionVersionIdsSpecification.cs b/src/core/Elsa.Core/Persistence/Specifications/ManyWorkflowDefinitionVersionIdsSpecification.cs new file mode 100644 index 000000000..0fd79b53f --- /dev/null +++ b/src/core/Elsa.Core/Persistence/Specifications/ManyWorkflowDefinitionVersionIdsSpecification.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Linq.Expressions; +using Elsa.Models; + +namespace Elsa.Persistence.Specifications +{ + public class ManyWorkflowDefinitionVersionIdsSpecification : Specification + { + public IEnumerable Ids { get; set; } + public ManyWorkflowDefinitionVersionIdsSpecification(IEnumerable ids) => Ids = ids; + public override Expression> ToExpression() => x => Ids.Contains(x.DefinitionVersionId); + } +} \ No newline at end of file diff --git a/src/core/Elsa.Core/Services/WorkflowPublisher.cs b/src/core/Elsa.Core/Services/WorkflowPublisher.cs index a150b55ca..85657a89c 100644 --- a/src/core/Elsa.Core/Services/WorkflowPublisher.cs +++ b/src/core/Elsa.Core/Services/WorkflowPublisher.cs @@ -1,19 +1,23 @@ +using System.Linq; using System.Threading; using System.Threading.Tasks; using Elsa.Models; using Elsa.Persistence; +using Elsa.Persistence.Specifications; namespace Elsa.Services { public class WorkflowPublisher : IWorkflowPublisher { private readonly IWorkflowDefinitionStore _workflowDefinitionStore; + private readonly IWorkflowInstanceStore _workflowInstanceStore; private readonly IIdGenerator _idGenerator; private readonly ICloner _cloner; - public WorkflowPublisher(IWorkflowDefinitionStore workflowDefinitionStore, IIdGenerator idGenerator, ICloner cloner) + public WorkflowPublisher(IWorkflowDefinitionStore workflowDefinitionStore, IWorkflowInstanceStore workflowInstanceStore, IIdGenerator idGenerator, ICloner cloner) { _workflowDefinitionStore = workflowDefinitionStore; + _workflowInstanceStore = workflowInstanceStore; _idGenerator = idGenerator; _cloner = cloner; } @@ -35,9 +39,7 @@ namespace Elsa.Services return definition; } - public async Task PublishAsync( - string workflowDefinitionId, - CancellationToken cancellationToken) + public async Task PublishAsync(string workflowDefinitionId, CancellationToken cancellationToken) { var definition = await _workflowDefinitionStore.FindByIdAsync( workflowDefinitionId, @@ -128,6 +130,17 @@ namespace Elsa.Services return draft; } + public async Task DeleteAsync(string workflowDefinitionId, CancellationToken cancellationToken) + { + var allVersions = await _workflowDefinitionStore.FindManyAsync(new WorkflowDefinitionIdSpecification(workflowDefinitionId), cancellationToken: cancellationToken); + var allVersionIds = allVersions.Select(x => x.DefinitionVersionId).ToList(); + + await _workflowInstanceStore.DeleteManyAsync(new WorkflowInstanceDefinitionIdSpecification(workflowDefinitionId), cancellationToken); + await _workflowDefinitionStore.DeleteManyAsync(new ManyWorkflowDefinitionVersionIdsSpecification(allVersionIds), cancellationToken); + } + + public Task DeleteAsync(WorkflowDefinition workflowDefinition, CancellationToken cancellationToken) => DeleteAsync(workflowDefinition.Id, cancellationToken); + private WorkflowDefinition Initialize(WorkflowDefinition workflowDefinition) { if (workflowDefinition.Id == null!) diff --git a/src/dashboards/blazor/ElsaDashboard.Application/Pages/WorkflowDefinitions/List.razor b/src/dashboards/blazor/ElsaDashboard.Application/Pages/WorkflowDefinitions/List.razor index 99d17d9eb..187bcbebd 100644 --- a/src/dashboards/blazor/ElsaDashboard.Application/Pages/WorkflowDefinitions/List.razor +++ b/src/dashboards/blazor/ElsaDashboard.Application/Pages/WorkflowDefinitions/List.razor @@ -14,56 +14,7 @@ - -
-

Pinned Workflows

- -
@@ -95,6 +46,9 @@ Name + + Display Name + Instances @@ -110,13 +64,20 @@ @foreach (var workflowDefinition in Definitions.Items) { - var displayName = workflowDefinition.DisplayName ?? workflowDefinition.Name ?? "Unnamed"; - var viewUrl = $"workflow-definitions/{workflowDefinition.DefinitionVersionId}/viewer"; + var name = string.IsNullOrWhiteSpace(workflowDefinition.Name) ? "-" : workflowDefinition.Name; + var displayName = !string.IsNullOrWhiteSpace(workflowDefinition.DisplayName) ? workflowDefinition.DisplayName : !string.IsNullOrWhiteSpace(workflowDefinition.Name) ? workflowDefinition.Name : "(Untitled)"; + var viewUrl = $"workflow-definitions/{workflowDefinition.DefinitionVersionId}/designer"; + + +
@displayName @@ -163,63 +124,6 @@ } -
- - -
+
\ No newline at end of file diff --git a/src/dashboards/blazor/ElsaDashboard.Application/Pages/WorkflowDefinitions/List.razor.cs b/src/dashboards/blazor/ElsaDashboard.Application/Pages/WorkflowDefinitions/List.razor.cs index 479f8d7d7..c233649c3 100644 --- a/src/dashboards/blazor/ElsaDashboard.Application/Pages/WorkflowDefinitions/List.razor.cs +++ b/src/dashboards/blazor/ElsaDashboard.Application/Pages/WorkflowDefinitions/List.razor.cs @@ -26,12 +26,12 @@ namespace ElsaDashboard.Application.Pages.WorkflowDefinitions private async Task OnDeleteWorkflowDefinitionClick(WorkflowDefinition workflowDefinition) { - var result = await ConfirmDialogService.Show("Delete Workflow Instance", "Are you sure you want to delete this workflow instance?", "Delete"); + var result = await ConfirmDialogService.Show("Delete Workflow Definition", "Are you sure you want to delete this workflow definition? This will also delete any and all of its workflow instances.", "Delete"); if (result.Cancelled) return; - //await WorkflowDefinitionService.DeleteAsync(workflowInstance.Id); + await WorkflowDefinitionService.DeleteAsync(workflowDefinition.Id); await LoadWorkflowDefinitionsAsync(); } } diff --git a/src/dashboards/blazor/ElsaDashboard.Application/Pages/WorkflowRegistry/List.razor b/src/dashboards/blazor/ElsaDashboard.Application/Pages/WorkflowRegistry/List.razor index f30cb3235..7319911b5 100644 --- a/src/dashboards/blazor/ElsaDashboard.Application/Pages/WorkflowRegistry/List.razor +++ b/src/dashboards/blazor/ElsaDashboard.Application/Pages/WorkflowRegistry/List.razor @@ -7,56 +7,6 @@
- -
-

Pinned Workflows

- -
@@ -108,11 +58,11 @@ var latestVersion = workflowBlueprints.First(); var publishedVersion = workflowBlueprints.FirstOrDefault(x => x.IsPublished); var displayName = latestVersion.DisplayName ?? latestVersion.Name ?? "Unnamed"; + var viewUrl = $"workflow-registry/{workflowBlueprintId}/viewer"; @@ -135,121 +85,20 @@ @(publishedVersion?.Version.ToString() ?? "-") - + View + + } -
- - -
\ No newline at end of file diff --git a/src/dashboards/blazor/ElsaDashboard.Backend/Rpc/WorkflowDefinitionService.cs b/src/dashboards/blazor/ElsaDashboard.Backend/Rpc/WorkflowDefinitionService.cs index 255a48584..21118dbed 100644 --- a/src/dashboards/blazor/ElsaDashboard.Backend/Rpc/WorkflowDefinitionService.cs +++ b/src/dashboards/blazor/ElsaDashboard.Backend/Rpc/WorkflowDefinitionService.cs @@ -23,5 +23,6 @@ namespace ElsaDashboard.Backend.Rpc public Task GetByVersionIdAsync(GetWorkflowDefinitionByVersionIdRequest request, CallContext context) => _elsaClient.WorkflowDefinitions.GetByVersionIdAsync(request.WorkflowDefinitionVersionId, context.CancellationToken); public async Task SaveAsync(SaveWorkflowDefinitionRequest request, CallContext context) => await _elsaClient.WorkflowDefinitions.SaveAsync(request, context.CancellationToken); + public async Task DeleteAsync(DeleteWorkflowDefinitionRequest request, CallContext context = default) => await _elsaClient.WorkflowDefinitions.DeleteAsync(request.WorkflowDefinitionId, context.CancellationToken); } } \ No newline at end of file diff --git a/src/dashboards/blazor/ElsaDashboard.Shared/Rpc/WorkflowDefinition/Extensions/WorkflowDefinitionServiceExtensions.cs b/src/dashboards/blazor/ElsaDashboard.Shared/Rpc/WorkflowDefinition/Extensions/WorkflowDefinitionServiceExtensions.cs index 8ea5dd703..df4056ba3 100644 --- a/src/dashboards/blazor/ElsaDashboard.Shared/Rpc/WorkflowDefinition/Extensions/WorkflowDefinitionServiceExtensions.cs +++ b/src/dashboards/blazor/ElsaDashboard.Shared/Rpc/WorkflowDefinition/Extensions/WorkflowDefinitionServiceExtensions.cs @@ -5,13 +5,9 @@ namespace ElsaDashboard.Shared.Rpc { public static class WorkflowDefinitionServiceExtensions { - public static async Task> ListAsync(this IWorkflowDefinitionService service, int? page = default, int? pageSize = default, VersionOptions? versionOptions = default) => - await service.ListAsync(new ListWorkflowDefinitionsRequest(page, pageSize, versionOptions)); - - public static async Task GetByIdAsync(this IWorkflowDefinitionService service, string workflowDefinitionId, VersionOptions? versionOptions = default) => - await service.GetByIdAsync(new GetWorkflowDefinitionByIdRequest(workflowDefinitionId, versionOptions)); - - public static async Task GetByVersionIdAsync(this IWorkflowDefinitionService service, string workflowDefinitionVersionId) => - await service.GetByVersionIdAsync(new GetWorkflowDefinitionByVersionIdRequest(workflowDefinitionVersionId)); + public static async Task> ListAsync(this IWorkflowDefinitionService service, int? page = default, int? pageSize = default, VersionOptions? versionOptions = default) => await service.ListAsync(new ListWorkflowDefinitionsRequest(page, pageSize, versionOptions)); + public static async Task GetByIdAsync(this IWorkflowDefinitionService service, string workflowDefinitionId, VersionOptions? versionOptions = default) => await service.GetByIdAsync(new GetWorkflowDefinitionByIdRequest(workflowDefinitionId, versionOptions)); + public static async Task GetByVersionIdAsync(this IWorkflowDefinitionService service, string workflowDefinitionVersionId) => await service.GetByVersionIdAsync(new GetWorkflowDefinitionByVersionIdRequest(workflowDefinitionVersionId)); + public static async Task DeleteAsync(this IWorkflowDefinitionService service, string workflowDefinitionId) => await service.DeleteAsync(new DeleteWorkflowDefinitionRequest(workflowDefinitionId)); } } \ No newline at end of file diff --git a/src/dashboards/blazor/ElsaDashboard.Shared/Rpc/WorkflowDefinition/Models/DeleteWorkflowDefinitionRequest.cs b/src/dashboards/blazor/ElsaDashboard.Shared/Rpc/WorkflowDefinition/Models/DeleteWorkflowDefinitionRequest.cs new file mode 100644 index 000000000..cfa9c394a --- /dev/null +++ b/src/dashboards/blazor/ElsaDashboard.Shared/Rpc/WorkflowDefinition/Models/DeleteWorkflowDefinitionRequest.cs @@ -0,0 +1,19 @@ +using ProtoBuf; + +namespace ElsaDashboard.Shared.Rpc +{ + [ProtoContract] + public class DeleteWorkflowDefinitionRequest + { + public DeleteWorkflowDefinitionRequest() + { + } + + public DeleteWorkflowDefinitionRequest(string workflowDefinitionId) + { + WorkflowDefinitionId = workflowDefinitionId; + } + + [ProtoMember(1)] public string WorkflowDefinitionId { get; set; } = default!; + } +} \ No newline at end of file diff --git a/src/dashboards/blazor/ElsaDashboard.Shared/Rpc/WorkflowDefinition/Services/IWorkflowDefinitionService.cs b/src/dashboards/blazor/ElsaDashboard.Shared/Rpc/WorkflowDefinition/Services/IWorkflowDefinitionService.cs index a5ed6e623..786d684a8 100644 --- a/src/dashboards/blazor/ElsaDashboard.Shared/Rpc/WorkflowDefinition/Services/IWorkflowDefinitionService.cs +++ b/src/dashboards/blazor/ElsaDashboard.Shared/Rpc/WorkflowDefinition/Services/IWorkflowDefinitionService.cs @@ -19,5 +19,8 @@ namespace ElsaDashboard.Shared.Rpc [Operation] Task SaveAsync(SaveWorkflowDefinitionRequest request, CallContext context = default); + + [Operation] + Task DeleteAsync(DeleteWorkflowDefinitionRequest request, CallContext context = default); } } \ No newline at end of file diff --git a/src/persistence/Elsa.Persistence.YesSql/Stores/YesSqlWorkflowDefinitionStore.cs b/src/persistence/Elsa.Persistence.YesSql/Stores/YesSqlWorkflowDefinitionStore.cs index 9239bdda1..8894d18ef 100644 --- a/src/persistence/Elsa.Persistence.YesSql/Stores/YesSqlWorkflowDefinitionStore.cs +++ b/src/persistence/Elsa.Persistence.YesSql/Stores/YesSqlWorkflowDefinitionStore.cs @@ -1,3 +1,4 @@ +using System.Linq; using System.Threading; using System.Threading.Tasks; using AutoMapper; @@ -8,6 +9,7 @@ using Elsa.Persistence.YesSql.Documents; using Elsa.Persistence.YesSql.Extensions; using Elsa.Persistence.YesSql.Indexes; using YesSql; +using YesSql.Services; using IIdGenerator = Elsa.Services.IIdGenerator; namespace Elsa.Persistence.YesSql.Stores @@ -24,9 +26,10 @@ namespace Elsa.Persistence.YesSql.Stores { return specification switch { - EntityIdSpecification entityIdSpecification => Query(x => x.DefinitionId == entityIdSpecification.Id), - VersionOptionsSpecification versionOptionsSpecification => Query().WithVersion(versionOptionsSpecification.VersionOptions), - WorkflowDefinitionIdSpecification definitionIdSpecification => definitionIdSpecification.VersionOptions == null ? Query(x => x.DefinitionId == definitionIdSpecification.Id) : Query(x => x.DefinitionId == definitionIdSpecification.Id).WithVersion(definitionIdSpecification.VersionOptions), + EntityIdSpecification s => Query(x => x.DefinitionId == s.Id), + VersionOptionsSpecification s => Query().WithVersion(s.VersionOptions), + WorkflowDefinitionIdSpecification s => s.VersionOptions == null ? Query(x => x.DefinitionId == s.Id) : Query(x => x.DefinitionId == s.Id).WithVersion(s.VersionOptions), + ManyWorkflowDefinitionVersionIdsSpecification s => Query(x => x.DefinitionVersionId.IsIn(s.Ids)), _ => AutoMapSpecification(specification) }; } diff --git a/src/server/Elsa.Server.Api/Endpoints/WorkflowDefinitions/Delete.cs b/src/server/Elsa.Server.Api/Endpoints/WorkflowDefinitions/Delete.cs new file mode 100644 index 000000000..8f2606d80 --- /dev/null +++ b/src/server/Elsa.Server.Api/Endpoints/WorkflowDefinitions/Delete.cs @@ -0,0 +1,37 @@ +using System.Threading; +using System.Threading.Tasks; +using Elsa.Services; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc; +using Swashbuckle.AspNetCore.Annotations; + +namespace Elsa.Server.Api.Endpoints.WorkflowDefinitions +{ + [ApiController] + [ApiVersion("1")] + [Route("v{apiVersion:apiVersion}/workflow-definitions/{id}")] + [Produces("application/json")] + public class Delete : ControllerBase + { + private readonly IWorkflowPublisher _workflowPublisher; + + public Delete(IWorkflowPublisher workflowPublisher) + { + _workflowPublisher = workflowPublisher; + } + + [HttpDelete] + [ProducesResponseType(StatusCodes.Status202Accepted)] + [SwaggerOperation( + Summary = "Deletes a workflow definition and all of its versions and workflow instances.", + Description = "Deletes a workflow definition and all of its versions and workflow instances.", + OperationId = "WorkflowDefinitions.Delete", + Tags = new[] { "WorkflowDefinitions" }) + ] + public async Task Handle(string id, CancellationToken cancellationToken) + { + await _workflowPublisher.DeleteAsync(id, cancellationToken); + return Accepted(); + } + } +} \ No newline at end of file