Implement delete workflow definition
This commit is contained in:
parent
1c006e3081
commit
460c75227d
|
|
@ -18,5 +18,8 @@ namespace Elsa.Client.Services
|
|||
|
||||
[Post("/v1/workflow-definitions")]
|
||||
Task<WorkflowDefinition> SaveAsync([Body] SaveWorkflowDefinitionRequest request, CancellationToken cancellationToken = default);
|
||||
|
||||
[Delete("/v1/workflow-definitions/{workflowDefinitionId}")]
|
||||
Task DeleteAsync(string workflowDefinitionId, CancellationToken cancellationToken = default);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
using System.Collections.Generic;
|
||||
using Elsa.Models;
|
||||
using MediatR;
|
||||
|
||||
namespace Elsa.Events
|
||||
{
|
||||
public class ManyWorkflowInstancesDeleted : INotification
|
||||
{
|
||||
public ManyWorkflowInstancesDeleted(IEnumerable<WorkflowInstance> workflowInstances)
|
||||
{
|
||||
WorkflowInstances = workflowInstances;
|
||||
}
|
||||
|
||||
public IEnumerable<WorkflowInstance> WorkflowInstances { get; }
|
||||
}
|
||||
}
|
||||
|
|
@ -13,7 +13,7 @@ namespace Elsa
|
|||
{
|
||||
public static class WorkflowBlueprintExtensions
|
||||
{
|
||||
public static ValueTask<T> GetActivityPropertyValue<TActivity, T>(
|
||||
public static ValueTask<T?> GetActivityPropertyValue<TActivity, T>(
|
||||
this IWorkflowBlueprint workflowBlueprint,
|
||||
string activityId,
|
||||
Expression<Func<TActivity, T>> propertyExpression,
|
||||
|
|
@ -25,15 +25,18 @@ namespace Elsa
|
|||
return GetActivityPropertyValue<T>(workflowBlueprint, activityId, propertyName, activityExecutionContext, cancellationToken);
|
||||
}
|
||||
|
||||
public static async ValueTask<T> GetActivityPropertyValue<T>(
|
||||
public static async ValueTask<T?> GetActivityPropertyValue<T>(
|
||||
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<object> GetActivityPropertyValue(
|
||||
public static async ValueTask<object?> GetActivityPropertyValue(
|
||||
this IWorkflowBlueprint workflowBlueprint,
|
||||
string activityId,
|
||||
string propertyName,
|
||||
|
|
|
|||
|
|
@ -7,17 +7,11 @@ namespace Elsa.Services
|
|||
public interface IWorkflowPublisher
|
||||
{
|
||||
WorkflowDefinition New();
|
||||
|
||||
Task<WorkflowDefinition?> PublishAsync(string workflowDefinitionId, CancellationToken cancellationToken = default);
|
||||
|
||||
Task<WorkflowDefinition> PublishAsync(
|
||||
WorkflowDefinition workflowDefinition,
|
||||
CancellationToken cancellationToken = default);
|
||||
|
||||
Task<WorkflowDefinition> PublishAsync(WorkflowDefinition workflowDefinition, CancellationToken cancellationToken = default);
|
||||
Task<WorkflowDefinition?> GetDraftAsync(string workflowDefinitionId, CancellationToken cancellationToken= default);
|
||||
|
||||
Task<WorkflowDefinition> SaveDraftAsync(
|
||||
WorkflowDefinition workflowDefinition,
|
||||
CancellationToken cancellationToken = default);
|
||||
Task<WorkflowDefinition> SaveDraftAsync(WorkflowDefinition workflowDefinition, CancellationToken cancellationToken = default);
|
||||
Task DeleteAsync(string workflowDefinitionId, CancellationToken cancellationToken = default);
|
||||
Task DeleteAsync(WorkflowDefinition workflowDefinition, CancellationToken cancellationToken = default);
|
||||
}
|
||||
}
|
||||
|
|
@ -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<WorkflowInstanceSaved>
|
||||
public class UpdateTriggers : INotificationHandler<WorkflowInstanceSaved>, INotificationHandler<ManyWorkflowInstancesDeleted>
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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<int> DeleteManyAsync(ISpecification<WorkflowInstance> 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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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<WorkflowDefinition>
|
||||
{
|
||||
public IEnumerable<string> Ids { get; set; }
|
||||
public ManyWorkflowDefinitionVersionIdsSpecification(IEnumerable<string> ids) => Ids = ids;
|
||||
public override Expression<Func<WorkflowDefinition, bool>> ToExpression() => x => Ids.Contains(x.DefinitionVersionId);
|
||||
}
|
||||
}
|
||||
|
|
@ -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<WorkflowDefinition?> PublishAsync(
|
||||
string workflowDefinitionId,
|
||||
CancellationToken cancellationToken)
|
||||
public async Task<WorkflowDefinition?> 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!)
|
||||
|
|
|
|||
|
|
@ -14,56 +14,7 @@
|
|||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Pinned projects -->
|
||||
<div class="px-4 mt-6 sm:px-6 lg:px-8">
|
||||
<h2 class="text-gray-500 text-xs font-medium uppercase tracking-wide">Pinned Workflows</h2>
|
||||
<ul class="grid grid-cols-1 gap-4 sm:gap-6 sm:grid-cols-2 xl:grid-cols-4 mt-3">
|
||||
<li x-data="{ open: false }" x-on:keydown.escape="open = false" x-on:click.away="open = false" class="relative col-span-1 flex shadow-sm rounded-md">
|
||||
<div class="flex-shrink-0 flex items-center justify-center w-16 bg-pink-600 text-white text-sm leading-5 font-medium rounded-l-md">
|
||||
DA
|
||||
</div>
|
||||
<div class="flex-1 flex items-center justify-between border-t border-r border-b border-gray-200 bg-white rounded-r-md truncate">
|
||||
<div class="flex-1 px-4 py-2 text-sm leading-5 truncate">
|
||||
<a href="#" class="text-gray-900 font-medium hover:text-gray-600 transition ease-in-out duration-150">
|
||||
Document Approval
|
||||
</a>
|
||||
<p class="text-gray-500">12 Instances</p>
|
||||
</div>
|
||||
<div class="flex-shrink-0 pr-2">
|
||||
<button x-on:click="open = !open" id="pinned-project-options-menu-0" aria-haspopup="true" class="w-8 h-8 inline-flex items-center justify-center text-gray-400 rounded-full bg-transparent hover:text-gray-500 focus:outline-none focus:text-gray-500 focus:bg-gray-100 transition ease-in-out duration-150">
|
||||
<!-- Heroicon name: dots-vertical -->
|
||||
<svg class="w-5 h-5" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor">
|
||||
<path d="M10 6a2 2 0 110-4 2 2 0 010 4zM10 12a2 2 0 110-4 2 2 0 010 4zM10 18a2 2 0 110-4 2 2 0 010 4z"/>
|
||||
</svg>
|
||||
</button>
|
||||
<div x-show="open"
|
||||
x-transition:enter="transition ease-out duration-100"
|
||||
x-transition:enter-start="transform opacity-0 scale-95"
|
||||
x-transition:enter-end="transform opacity-100 scale-100"
|
||||
x-transition:leave="transition ease-in duration-75"
|
||||
x-transition:leave-start="transform opacity-100 scale-100"
|
||||
x-transition:leave-end="transform opacity-0 scale-95"
|
||||
class="z-10 mx-3 origin-top-right absolute right-10 top-3 w-48 mt-1 rounded-md shadow-lg">
|
||||
<div class="rounded-md bg-white shadow-xs" role="menu" aria-orientation="vertical" aria-labelledby="pinned-project-options-menu-0">
|
||||
<div class="py-1">
|
||||
<a href="#" class="block px-4 py-2 text-sm leading-5 text-gray-700 hover:bg-gray-100 hover:text-gray-900 focus:outline-none focus:bg-gray-100 focus:text-gray-900" role="menuitem">Edit</a>
|
||||
</div>
|
||||
<div class="border-t border-gray-100"></div>
|
||||
<div class="py-1">
|
||||
<a href="#" class="block px-4 py-2 text-sm leading-5 text-gray-700 hover:bg-gray-100 hover:text-gray-900 focus:outline-none focus:bg-gray-100 focus:text-gray-900" role="menuitem">
|
||||
Removed
|
||||
from pinned
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<!-- More project cards... -->
|
||||
</ul>
|
||||
</div>
|
||||
<!-- Projects list (only on smallest breakpoint) -->
|
||||
<div class="mt-10 sm:hidden">
|
||||
<div class="px-4 sm:px-6">
|
||||
|
|
@ -95,6 +46,9 @@
|
|||
<th class="px-6 py-3 border-b border-gray-200 bg-gray-50 text-left text-xs leading-4 font-medium text-gray-500 uppercase tracking-wider">
|
||||
<span class="lg:pl-2">Name</span>
|
||||
</th>
|
||||
<th class="px-6 py-3 border-b border-gray-200 bg-gray-50 text-left text-xs leading-4 font-medium text-gray-500 uppercase tracking-wider">
|
||||
<span class="lg:pl-2">Display Name</span>
|
||||
</th>
|
||||
<th class="px-6 py-3 border-b border-gray-200 bg-gray-50 text-left text-xs leading-4 font-medium text-gray-500 uppercase tracking-wider">
|
||||
Instances
|
||||
</th>
|
||||
|
|
@ -110,13 +64,20 @@
|
|||
<tbody class="bg-white divide-y divide-gray-100">
|
||||
@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";
|
||||
|
||||
<tr>
|
||||
<td class="px-6 py-3 whitespace-no-wrap text-sm leading-5 font-medium text-gray-900">
|
||||
<div class="flex items-center space-x-3 lg:pl-2">
|
||||
<div class="flex-shrink-0 w-2.5 h-2.5 rounded-full bg-pink-600"></div>
|
||||
<a href="@viewUrl" class="truncate hover:text-gray-600">
|
||||
<span>@name</span>
|
||||
</a>
|
||||
</div>
|
||||
</td>
|
||||
<td class="px-6 py-3 whitespace-no-wrap text-sm leading-5 font-medium text-gray-900">
|
||||
<div class="flex items-center space-x-3 lg:pl-2">
|
||||
<a href="@viewUrl" class="truncate hover:text-gray-600">
|
||||
<span>@displayName</span>
|
||||
</a>
|
||||
|
|
@ -163,63 +124,6 @@
|
|||
}
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="bg-white px-4 py-3 flex items-center justify-between border-t border-gray-200 sm:px-6">
|
||||
<div class="flex-1 flex justify-between sm:hidden">
|
||||
<a href="#" class="relative inline-flex items-center px-4 py-2 border border-gray-300 text-sm leading-5 font-medium rounded-md text-gray-700 bg-white hover:text-gray-500 focus:outline-none focus:shadow-outline-blue focus:border-blue-300 active:bg-gray-100 active:text-gray-700 transition ease-in-out duration-150">
|
||||
Previous
|
||||
</a>
|
||||
<a href="#" class="ml-3 relative inline-flex items-center px-4 py-2 border border-gray-300 text-sm leading-5 font-medium rounded-md text-gray-700 bg-white hover:text-gray-500 focus:outline-none focus:shadow-outline-blue focus:border-blue-300 active:bg-gray-100 active:text-gray-700 transition ease-in-out duration-150">
|
||||
Next
|
||||
</a>
|
||||
</div>
|
||||
<div class="hidden sm:flex-1 sm:flex sm:items-center sm:justify-between">
|
||||
<div>
|
||||
<p class="text-sm leading-5 text-gray-700">
|
||||
Showing
|
||||
<span class="font-medium">1</span>
|
||||
to
|
||||
<span class="font-medium">10</span>
|
||||
of
|
||||
<span class="font-medium">97</span>
|
||||
results
|
||||
</p>
|
||||
</div>
|
||||
<div>
|
||||
<nav class="relative z-0 inline-flex shadow-sm">
|
||||
<a href="#" class="relative inline-flex items-center px-2 py-2 rounded-l-md border border-gray-300 bg-white text-sm leading-5 font-medium text-gray-500 hover:text-gray-400 focus:z-10 focus:outline-none focus:border-blue-300 focus:shadow-outline-blue active:bg-gray-100 active:text-gray-500 transition ease-in-out duration-150" aria-label="Previous">
|
||||
<svg class="h-5 w-5" x-description="Heroicon name: chevron-left" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor">
|
||||
<path fill-rule="evenodd" d="M12.707 5.293a1 1 0 010 1.414L9.414 10l3.293 3.293a1 1 0 01-1.414 1.414l-4-4a1 1 0 010-1.414l4-4a1 1 0 011.414 0z" clip-rule="evenodd"></path>
|
||||
</svg>
|
||||
</a>
|
||||
<a href="#" class="-ml-px relative inline-flex items-center px-4 py-2 border border-gray-300 bg-white text-sm leading-5 font-medium text-gray-700 hover:text-gray-500 focus:z-10 focus:outline-none focus:border-blue-300 focus:shadow-outline-blue active:bg-gray-100 active:text-gray-700 transition ease-in-out duration-150">
|
||||
1
|
||||
</a>
|
||||
<a href="#" class="-ml-px relative inline-flex items-center px-4 py-2 border border-gray-300 bg-white text-sm leading-5 font-medium text-gray-700 hover:text-gray-500 focus:z-10 focus:outline-none focus:border-blue-300 focus:shadow-outline-blue active:bg-gray-100 active:text-gray-700 transition ease-in-out duration-150">
|
||||
2
|
||||
</a>
|
||||
<a href="#" class="hidden md:inline-flex -ml-px relative items-center px-4 py-2 border border-gray-300 bg-white text-sm leading-5 font-medium text-gray-700 hover:text-gray-500 focus:z-10 focus:outline-none focus:border-blue-300 focus:shadow-outline-blue active:bg-gray-100 active:text-gray-700 transition ease-in-out duration-150">
|
||||
3
|
||||
</a>
|
||||
<span class="-ml-px relative inline-flex items-center px-4 py-2 border border-gray-300 bg-white text-sm leading-5 font-medium text-gray-700">
|
||||
...
|
||||
</span>
|
||||
<a href="#" class="hidden md:inline-flex -ml-px relative items-center px-4 py-2 border border-gray-300 bg-white text-sm leading-5 font-medium text-gray-700 hover:text-gray-500 focus:z-10 focus:outline-none focus:border-blue-300 focus:shadow-outline-blue active:bg-gray-100 active:text-gray-700 transition ease-in-out duration-150">
|
||||
8
|
||||
</a>
|
||||
<a href="#" class="-ml-px relative inline-flex items-center px-4 py-2 border border-gray-300 bg-white text-sm leading-5 font-medium text-gray-700 hover:text-gray-500 focus:z-10 focus:outline-none focus:border-blue-300 focus:shadow-outline-blue active:bg-gray-100 active:text-gray-700 transition ease-in-out duration-150">
|
||||
9
|
||||
</a>
|
||||
<a href="#" class="-ml-px relative inline-flex items-center px-4 py-2 border border-gray-300 bg-white text-sm leading-5 font-medium text-gray-700 hover:text-gray-500 focus:z-10 focus:outline-none focus:border-blue-300 focus:shadow-outline-blue active:bg-gray-100 active:text-gray-700 transition ease-in-out duration-150">
|
||||
10
|
||||
</a>
|
||||
<a href="#" class="-ml-px relative inline-flex items-center px-2 py-2 rounded-r-md border border-gray-300 bg-white text-sm leading-5 font-medium text-gray-500 hover:text-gray-400 focus:z-10 focus:outline-none focus:border-blue-300 focus:shadow-outline-blue active:bg-gray-100 active:text-gray-500 transition ease-in-out duration-150" aria-label="Next">
|
||||
<svg class="h-5 w-5" x-description="Heroicon name: chevron-right" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor">
|
||||
<path fill-rule="evenodd" d="M7.293 14.707a1 1 0 010-1.414L10.586 10 7.293 6.707a1 1 0 011.414-1.414l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414 0z" clip-rule="evenodd"></path>
|
||||
</svg>
|
||||
</a>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<Pager Page="@Definitions.Page" PageSize="@Definitions.PageSize" TotalCount="@Definitions.TotalCount"/>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,56 +7,6 @@
|
|||
</h1>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Pinned projects -->
|
||||
<div class="px-4 mt-6 sm:px-6 lg:px-8">
|
||||
<h2 class="text-gray-500 text-xs font-medium uppercase tracking-wide">Pinned Workflows</h2>
|
||||
<ul class="grid grid-cols-1 gap-4 sm:gap-6 sm:grid-cols-2 xl:grid-cols-4 mt-3">
|
||||
<li x-data="{ open: false }" x-on:keydown.escape="open = false" x-on:click.away="open = false" class="relative col-span-1 flex shadow-sm rounded-md">
|
||||
<div class="flex-shrink-0 flex items-center justify-center w-16 bg-pink-600 text-white text-sm leading-5 font-medium rounded-l-md">
|
||||
DA
|
||||
</div>
|
||||
<div class="flex-1 flex items-center justify-between border-t border-r border-b border-gray-200 bg-white rounded-r-md truncate">
|
||||
<div class="flex-1 px-4 py-2 text-sm leading-5 truncate">
|
||||
<a href="#" class="text-gray-900 font-medium hover:text-gray-600 transition ease-in-out duration-150">
|
||||
Document Approval
|
||||
</a>
|
||||
<p class="text-gray-500">12 Instances</p>
|
||||
</div>
|
||||
<div class="flex-shrink-0 pr-2">
|
||||
<button x-on:click="open = !open" id="pinned-project-options-menu-0" aria-haspopup="true" class="w-8 h-8 inline-flex items-center justify-center text-gray-400 rounded-full bg-transparent hover:text-gray-500 focus:outline-none focus:text-gray-500 focus:bg-gray-100 transition ease-in-out duration-150">
|
||||
<!-- Heroicon name: dots-vertical -->
|
||||
<svg class="w-5 h-5" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor">
|
||||
<path d="M10 6a2 2 0 110-4 2 2 0 010 4zM10 12a2 2 0 110-4 2 2 0 010 4zM10 18a2 2 0 110-4 2 2 0 010 4z"/>
|
||||
</svg>
|
||||
</button>
|
||||
<div x-show="open"
|
||||
x-transition:enter="transition ease-out duration-100"
|
||||
x-transition:enter-start="transform opacity-0 scale-95"
|
||||
x-transition:enter-end="transform opacity-100 scale-100"
|
||||
x-transition:leave="transition ease-in duration-75"
|
||||
x-transition:leave-start="transform opacity-100 scale-100"
|
||||
x-transition:leave-end="transform opacity-0 scale-95"
|
||||
class="z-10 mx-3 origin-top-right absolute right-10 top-3 w-48 mt-1 rounded-md shadow-lg">
|
||||
<div class="rounded-md bg-white shadow-xs" role="menu" aria-orientation="vertical" aria-labelledby="pinned-project-options-menu-0">
|
||||
<div class="py-1">
|
||||
<a href="#" class="block px-4 py-2 text-sm leading-5 text-gray-700 hover:bg-gray-100 hover:text-gray-900 focus:outline-none focus:bg-gray-100 focus:text-gray-900" role="menuitem">Edit</a>
|
||||
</div>
|
||||
<div class="border-t border-gray-100"></div>
|
||||
<div class="py-1">
|
||||
<a href="#" class="block px-4 py-2 text-sm leading-5 text-gray-700 hover:bg-gray-100 hover:text-gray-900 focus:outline-none focus:bg-gray-100 focus:text-gray-900" role="menuitem">
|
||||
Removed
|
||||
from pinned
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<!-- More project cards... -->
|
||||
</ul>
|
||||
</div>
|
||||
<!-- Projects list (only on smallest breakpoint) -->
|
||||
<div class="mt-10 sm:hidden">
|
||||
<div class="px-4 sm:px-6">
|
||||
|
|
@ -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";
|
||||
<tr>
|
||||
<td class="px-6 py-3 whitespace-no-wrap text-sm leading-5 font-medium text-gray-900">
|
||||
<div class="flex items-center space-x-3 lg:pl-2">
|
||||
<div class="flex-shrink-0 w-2.5 h-2.5 rounded-full bg-pink-600"></div>
|
||||
<a href="@($"workflow-registry/{workflowBlueprintId}/viewer")" class="truncate hover:text-gray-600">
|
||||
<a href="@viewUrl" class="truncate hover:text-gray-600">
|
||||
<span>@displayName</span>
|
||||
</a>
|
||||
</div>
|
||||
|
|
@ -135,121 +85,20 @@
|
|||
@(publishedVersion?.Version.ToString() ?? "-")
|
||||
</td>
|
||||
<td class="pr-6">
|
||||
<div x-data="{ open: false }" x-on:keydown.escape="open = false" x-on:click.away="open = false" class="relative flex justify-end items-center">
|
||||
<button x-on:click="open = !open" id="project-options-menu-0" aria-has-popup="true" type="button" class="w-8 h-8 inline-flex items-center justify-center text-gray-400 rounded-full bg-transparent hover:text-gray-500 focus:outline-none focus:text-gray-500 focus:bg-gray-100 transition ease-in-out duration-150">
|
||||
<!-- Heroicon name: dots-vertical -->
|
||||
<svg class="w-5 h-5" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor">
|
||||
<path d="M10 6a2 2 0 110-4 2 2 0 010 4zM10 12a2 2 0 110-4 2 2 0 010 4zM10 18a2 2 0 110-4 2 2 0 010 4z"/>
|
||||
<ContextMenu>
|
||||
<ContextMenuItem Url="@viewUrl">
|
||||
<!-- Heroicon name: pencil-alt -->
|
||||
<svg class="mr-3 h-5 w-5 text-gray-400 group-hover:text-gray-500 group-focus:text-gray-500" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor">
|
||||
<path d="M17.414 2.586a2 2 0 00-2.828 0L7 10.172V13h2.828l7.586-7.586a2 2 0 000-2.828z"/>
|
||||
<path fill-rule="evenodd" d="M2 6a2 2 0 012-2h4a1 1 0 010 2H4v10h10v-4a1 1 0 112 0v4a2 2 0 01-2 2H4a2 2 0 01-2-2V6z" clip-rule="evenodd"/>
|
||||
</svg>
|
||||
</button>
|
||||
<div x-show="open"
|
||||
x-transition:enter="transition ease-out duration-100"
|
||||
x-transition:enter-start="transform opacity-0 scale-95"
|
||||
x-transition:leave="transition ease-in duration-75"
|
||||
x-transition:leave-start="transform opacity-100 scale-100"
|
||||
x-transition:leave-end="transform opacity-0 scale-95"
|
||||
class="z-10 mx-3 origin-top-right absolute right-7 top-0 w-48 mt-1 rounded-md shadow-lg">
|
||||
<div class="rounded-md bg-white shadow-xs" role="menu" aria-orientation="vertical" aria-labelledby="project-options-menu-0">
|
||||
<div class="py-1">
|
||||
<a href="@($"workflow-registry/{workflowBlueprintId}/viewer")" class="group flex items-center px-4 py-2 text-sm leading-5 text-gray-700 hover:bg-gray-100 hover:text-gray-900 focus:outline-none focus:bg-gray-100 focus:text-gray-900" role="menuitem">
|
||||
<!-- Heroicon name: pencil-alt -->
|
||||
<svg class="mr-3 h-5 w-5 text-gray-400 group-hover:text-gray-500 group-focus:text-gray-500" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor">
|
||||
<path d="M17.414 2.586a2 2 0 00-2.828 0L7 10.172V13h2.828l7.586-7.586a2 2 0 000-2.828z"/>
|
||||
<path fill-rule="evenodd" d="M2 6a2 2 0 012-2h4a1 1 0 010 2H4v10h10v-4a1 1 0 112 0v4a2 2 0 01-2 2H4a2 2 0 01-2-2V6z" clip-rule="evenodd"/>
|
||||
</svg>
|
||||
Edit
|
||||
</a>
|
||||
<a href="#" class="group flex items-center px-4 py-2 text-sm leading-5 text-gray-700 hover:bg-gray-100 hover:text-gray-900 focus:outline-none focus:bg-gray-100 focus:text-gray-900" role="menuitem">
|
||||
<!-- Heroicon name: duplicate -->
|
||||
<svg class="mr-3 h-5 w-5 text-gray-400 group-hover:text-gray-500 group-focus:text-gray-500" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor">
|
||||
<path d="M7 9a2 2 0 012-2h6a2 2 0 012 2v6a2 2 0 01-2 2H9a2 2 0 01-2-2V9z"/>
|
||||
<path d="M5 3a2 2 0 00-2 2v6a2 2 0 002 2V5h8a2 2 0 00-2-2H5z"/>
|
||||
</svg>
|
||||
Duplicate
|
||||
</a>
|
||||
<a href="#" class="group flex items-center px-4 py-2 text-sm leading-5 text-gray-700 hover:bg-gray-100 hover:text-gray-900 focus:outline-none focus:bg-gray-100 focus:text-gray-900" role="menuitem">
|
||||
<!-- Heroicon name: user-add -->
|
||||
<svg class="mr-3 h-5 w-5 text-gray-400 group-hover:text-gray-500 group-focus:text-gray-500" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor">
|
||||
<path d="M8 9a3 3 0 100-6 3 3 0 000 6zM8 11a6 6 0 016 6H2a6 6 0 016-6zM16 7a1 1 0 10-2 0v1h-1a1 1 0 100 2h1v1a1 1 0 102 0v-1h1a1 1 0 100-2h-1V7z"/>
|
||||
</svg>
|
||||
Share
|
||||
</a>
|
||||
</div>
|
||||
<div class="border-t border-gray-100"></div>
|
||||
<div class="py-1">
|
||||
<a href="#" class="group flex items-center px-4 py-2 text-sm leading-5 text-gray-700 hover:bg-gray-100 hover:text-gray-900 focus:outline-none focus:bg-gray-100 focus:text-gray-900" role="menuitem">
|
||||
<!-- Heroicon name: trash -->
|
||||
<svg class="mr-3 h-5 w-5 text-gray-400 group-hover:text-gray-500 group-focus:text-gray-500" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor">
|
||||
<path fill-rule="evenodd" d="M9 2a1 1 0 00-.894.553L7.382 4H4a1 1 0 000 2v10a2 2 0 002 2h8a2 2 0 002-2V6a1 1 0 100-2h-3.382l-.724-1.447A1 1 0 0011 2H9zM7 8a1 1 0 012 0v6a1 1 0 11-2 0V8zm5-1a1 1 0 00-1 1v6a1 1 0 102 0V8a1 1 0 00-1-1z" clip-rule="evenodd"/>
|
||||
</svg>
|
||||
Delete
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
View
|
||||
</ContextMenuItem>
|
||||
</ContextMenu>
|
||||
</td>
|
||||
</tr>
|
||||
}
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="bg-white px-4 py-3 flex items-center justify-between border-t border-gray-200 sm:px-6">
|
||||
<div class="flex-1 flex justify-between sm:hidden">
|
||||
<a href="#" class="relative inline-flex items-center px-4 py-2 border border-gray-300 text-sm leading-5 font-medium rounded-md text-gray-700 bg-white hover:text-gray-500 focus:outline-none focus:shadow-outline-blue focus:border-blue-300 active:bg-gray-100 active:text-gray-700 transition ease-in-out duration-150">
|
||||
Previous
|
||||
</a>
|
||||
<a href="#" class="ml-3 relative inline-flex items-center px-4 py-2 border border-gray-300 text-sm leading-5 font-medium rounded-md text-gray-700 bg-white hover:text-gray-500 focus:outline-none focus:shadow-outline-blue focus:border-blue-300 active:bg-gray-100 active:text-gray-700 transition ease-in-out duration-150">
|
||||
Next
|
||||
</a>
|
||||
</div>
|
||||
<div class="hidden sm:flex-1 sm:flex sm:items-center sm:justify-between">
|
||||
<div>
|
||||
<p class="text-sm leading-5 text-gray-700">
|
||||
Showing
|
||||
<span class="font-medium">1</span>
|
||||
to
|
||||
<span class="font-medium">10</span>
|
||||
of
|
||||
<span class="font-medium">97</span>
|
||||
results
|
||||
</p>
|
||||
</div>
|
||||
<div>
|
||||
<nav class="relative z-0 inline-flex shadow-sm">
|
||||
<a href="#" class="relative inline-flex items-center px-2 py-2 rounded-l-md border border-gray-300 bg-white text-sm leading-5 font-medium text-gray-500 hover:text-gray-400 focus:z-10 focus:outline-none focus:border-blue-300 focus:shadow-outline-blue active:bg-gray-100 active:text-gray-500 transition ease-in-out duration-150" aria-label="Previous">
|
||||
<svg class="h-5 w-5" x-description="Heroicon name: chevron-left" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor">
|
||||
<path fill-rule="evenodd" d="M12.707 5.293a1 1 0 010 1.414L9.414 10l3.293 3.293a1 1 0 01-1.414 1.414l-4-4a1 1 0 010-1.414l4-4a1 1 0 011.414 0z" clip-rule="evenodd"></path>
|
||||
</svg>
|
||||
</a>
|
||||
<a href="#" class="-ml-px relative inline-flex items-center px-4 py-2 border border-gray-300 bg-white text-sm leading-5 font-medium text-gray-700 hover:text-gray-500 focus:z-10 focus:outline-none focus:border-blue-300 focus:shadow-outline-blue active:bg-gray-100 active:text-gray-700 transition ease-in-out duration-150">
|
||||
1
|
||||
</a>
|
||||
<a href="#" class="-ml-px relative inline-flex items-center px-4 py-2 border border-gray-300 bg-white text-sm leading-5 font-medium text-gray-700 hover:text-gray-500 focus:z-10 focus:outline-none focus:border-blue-300 focus:shadow-outline-blue active:bg-gray-100 active:text-gray-700 transition ease-in-out duration-150">
|
||||
2
|
||||
</a>
|
||||
<a href="#" class="hidden md:inline-flex -ml-px relative items-center px-4 py-2 border border-gray-300 bg-white text-sm leading-5 font-medium text-gray-700 hover:text-gray-500 focus:z-10 focus:outline-none focus:border-blue-300 focus:shadow-outline-blue active:bg-gray-100 active:text-gray-700 transition ease-in-out duration-150">
|
||||
3
|
||||
</a>
|
||||
<span class="-ml-px relative inline-flex items-center px-4 py-2 border border-gray-300 bg-white text-sm leading-5 font-medium text-gray-700">
|
||||
...
|
||||
</span>
|
||||
<a href="#" class="hidden md:inline-flex -ml-px relative items-center px-4 py-2 border border-gray-300 bg-white text-sm leading-5 font-medium text-gray-700 hover:text-gray-500 focus:z-10 focus:outline-none focus:border-blue-300 focus:shadow-outline-blue active:bg-gray-100 active:text-gray-700 transition ease-in-out duration-150">
|
||||
8
|
||||
</a>
|
||||
<a href="#" class="-ml-px relative inline-flex items-center px-4 py-2 border border-gray-300 bg-white text-sm leading-5 font-medium text-gray-700 hover:text-gray-500 focus:z-10 focus:outline-none focus:border-blue-300 focus:shadow-outline-blue active:bg-gray-100 active:text-gray-700 transition ease-in-out duration-150">
|
||||
9
|
||||
</a>
|
||||
<a href="#" class="-ml-px relative inline-flex items-center px-4 py-2 border border-gray-300 bg-white text-sm leading-5 font-medium text-gray-700 hover:text-gray-500 focus:z-10 focus:outline-none focus:border-blue-300 focus:shadow-outline-blue active:bg-gray-100 active:text-gray-700 transition ease-in-out duration-150">
|
||||
10
|
||||
</a>
|
||||
<a href="#" class="-ml-px relative inline-flex items-center px-2 py-2 rounded-r-md border border-gray-300 bg-white text-sm leading-5 font-medium text-gray-500 hover:text-gray-400 focus:z-10 focus:outline-none focus:border-blue-300 focus:shadow-outline-blue active:bg-gray-100 active:text-gray-500 transition ease-in-out duration-150" aria-label="Next">
|
||||
<svg class="h-5 w-5" x-description="Heroicon name: chevron-right" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor">
|
||||
<path fill-rule="evenodd" d="M7.293 14.707a1 1 0 010-1.414L10.586 10 7.293 6.707a1 1 0 011.414-1.414l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414 0z" clip-rule="evenodd"></path>
|
||||
</svg>
|
||||
</a>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -23,5 +23,6 @@ namespace ElsaDashboard.Backend.Rpc
|
|||
|
||||
public Task<WorkflowDefinition> GetByVersionIdAsync(GetWorkflowDefinitionByVersionIdRequest request, CallContext context) => _elsaClient.WorkflowDefinitions.GetByVersionIdAsync(request.WorkflowDefinitionVersionId, context.CancellationToken);
|
||||
public async Task<WorkflowDefinition> 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);
|
||||
}
|
||||
}
|
||||
|
|
@ -5,13 +5,9 @@ namespace ElsaDashboard.Shared.Rpc
|
|||
{
|
||||
public static class WorkflowDefinitionServiceExtensions
|
||||
{
|
||||
public static async Task<PagedList<WorkflowDefinition>> 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<WorkflowDefinition> GetByIdAsync(this IWorkflowDefinitionService service, string workflowDefinitionId, VersionOptions? versionOptions = default) =>
|
||||
await service.GetByIdAsync(new GetWorkflowDefinitionByIdRequest(workflowDefinitionId, versionOptions));
|
||||
|
||||
public static async Task<WorkflowDefinition> GetByVersionIdAsync(this IWorkflowDefinitionService service, string workflowDefinitionVersionId) =>
|
||||
await service.GetByVersionIdAsync(new GetWorkflowDefinitionByVersionIdRequest(workflowDefinitionVersionId));
|
||||
public static async Task<PagedList<WorkflowDefinition>> 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<WorkflowDefinition> GetByIdAsync(this IWorkflowDefinitionService service, string workflowDefinitionId, VersionOptions? versionOptions = default) => await service.GetByIdAsync(new GetWorkflowDefinitionByIdRequest(workflowDefinitionId, versionOptions));
|
||||
public static async Task<WorkflowDefinition> 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));
|
||||
}
|
||||
}
|
||||
|
|
@ -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!;
|
||||
}
|
||||
}
|
||||
|
|
@ -19,5 +19,8 @@ namespace ElsaDashboard.Shared.Rpc
|
|||
|
||||
[Operation]
|
||||
Task<WorkflowDefinition> SaveAsync(SaveWorkflowDefinitionRequest request, CallContext context = default);
|
||||
|
||||
[Operation]
|
||||
Task DeleteAsync(DeleteWorkflowDefinitionRequest request, CallContext context = default);
|
||||
}
|
||||
}
|
||||
|
|
@ -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<WorkflowDefinition> entityIdSpecification => Query<WorkflowDefinitionIndex>(x => x.DefinitionId == entityIdSpecification.Id),
|
||||
VersionOptionsSpecification versionOptionsSpecification => Query<WorkflowDefinitionIndex>().WithVersion(versionOptionsSpecification.VersionOptions),
|
||||
WorkflowDefinitionIdSpecification definitionIdSpecification => definitionIdSpecification.VersionOptions == null ? Query<WorkflowDefinitionIndex>(x => x.DefinitionId == definitionIdSpecification.Id) : Query<WorkflowDefinitionIndex>(x => x.DefinitionId == definitionIdSpecification.Id).WithVersion(definitionIdSpecification.VersionOptions),
|
||||
EntityIdSpecification<WorkflowDefinition> s => Query<WorkflowDefinitionIndex>(x => x.DefinitionId == s.Id),
|
||||
VersionOptionsSpecification s => Query<WorkflowDefinitionIndex>().WithVersion(s.VersionOptions),
|
||||
WorkflowDefinitionIdSpecification s => s.VersionOptions == null ? Query<WorkflowDefinitionIndex>(x => x.DefinitionId == s.Id) : Query<WorkflowDefinitionIndex>(x => x.DefinitionId == s.Id).WithVersion(s.VersionOptions),
|
||||
ManyWorkflowDefinitionVersionIdsSpecification s => Query<WorkflowDefinitionIndex>(x => x.DefinitionVersionId.IsIn(s.Ids)),
|
||||
_ => AutoMapSpecification<WorkflowDefinitionIndex>(specification)
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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<IActionResult> Handle(string id, CancellationToken cancellationToken)
|
||||
{
|
||||
await _workflowPublisher.DeleteAsync(id, cancellationToken);
|
||||
return Accepted();
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue