Implement workflow settings

This commit is contained in:
Sipke Schoorstra 2020-12-27 21:02:14 +01:00
parent 5f08df0556
commit c6d68875c1
21 changed files with 193 additions and 116 deletions

View file

@ -13,12 +13,12 @@ namespace Elsa.Client.Models
Connections = new List<ConnectionDefinition>();
}
[DataMember(Order = 1)] public int Id { get; set; }
[DataMember(Order = 2)] public string? Name { get; set; }
[DataMember(Order = 3)] public string? DisplayName { get; set; }
[DataMember(Order = 4)] public string? Description { get; set; }
[DataMember(Order = 5)] public string WorkflowDefinitionId { get; set; } = default!;
[DataMember(Order = 6)] public string WorkflowDefinitionVersionId { get; set; } = default!;
[DataMember(Order = 1)] public string Id { get; set; } = default!;
[DataMember(Order = 2)] public string DefinitionVersionId { get; set; } = default!;
[DataMember(Order = 3)] public string TenantId { get; set; } = default!;
[DataMember(Order = 4)] public string? Name { get; set; }
[DataMember(Order = 5)] public string? DisplayName { get; set; }
[DataMember(Order = 6)] public string? Description { get; set; }
[DataMember(Order = 7)] public int Version { get; set; }
[DataMember(Order = 8)] public Variables? Variables { get; set; }
[DataMember(Order = 9)] public WorkflowContextOptions? ContextOptions { get; set; }

View file

@ -13,6 +13,6 @@ namespace Elsa
string id,
VersionOptions versionOptions,
CancellationToken cancellationToken = default) =>
store.FindAsync(new WorkflowDefinitionIdSpecification(id).And(new VersionOptionsSpecification(versionOptions)), cancellationToken);
store.FindAsync(new WorkflowDefinitionIdSpecification(id, versionOptions), cancellationToken);
}
}

View file

@ -7,7 +7,8 @@ namespace Elsa.Persistence.Specifications
public class WorkflowDefinitionIdSpecification : Specification<WorkflowDefinition>
{
public string Id { get; set; }
public WorkflowDefinitionIdSpecification(string id) => Id = id;
public override Expression<Func<WorkflowDefinition, bool>> ToExpression() => x => x.Id == Id;
public VersionOptions? VersionOptions { get; set; }
public WorkflowDefinitionIdSpecification(string id, VersionOptions? versionOptions = default) => (Id, VersionOptions) = (id, versionOptions);
public override Expression<Func<WorkflowDefinition, bool>> ToExpression() => VersionOptions == null ? x => x.Id == Id : x => x.Id == Id && x.WithVersion(VersionOptions);
}
}

View file

@ -11,22 +11,23 @@
"start": "npm run serve"
},
"dependencies": {
"@tailwindcss/ui": "^0.6.2",
"autoprefixer": "10.0.1",
"@tailwindcss/ui": "^0.7.2",
"@tailwindcss/forms": "^0.2.1",
"autoprefixer": "10.1.0",
"onchange": "^7.1.0",
"tailwindcss": "1.8.10"
"tailwindcss": "2.0.2"
},
"devDependencies": {
"concurrently": "^5.3.0",
"cross-env": "^7.0.2",
"cross-env": "^7.0.3",
"cssnano": "^4.1.10",
"htmlnano": "^0.2.7",
"htmlnano": "^0.2.8",
"live-server": "^1.2.1",
"postcss": "8.1.0",
"postcss-cli": "8.0.0",
"posthtml": "^0.13.4",
"posthtml-cli": "^0.8.0",
"postcss": "8.2.1",
"postcss-cli": "8.3.1",
"posthtml": "^0.15.1",
"posthtml-cli": "^0.9.1",
"posthtml-include": "^1.6.0",
"posthtml-modules": "^0.6.2"
"posthtml-modules": "^0.6.4"
}
}

View file

@ -15,6 +15,7 @@ module.exports = {
plugins: [
require('@tailwindcss/ui')({
layout: 'sidebar',
})
}),
require('@tailwindcss/forms')
],
};

View file

@ -0,0 +1,10 @@
namespace ElsaDashboard.Application.Models
{
public record TabItem(string Text, string Name)
{
public TabItem(string text) : this(text, text)
{
}
}
}

View file

@ -1,10 +1,25 @@
@page "/workflow-definitions/designer"
@page "/workflow-definitions/{workflowDefinitionId}/designer"
<div class="flex-0 border-b border-gray-200 px-4 py-4 sm:flex sm:items-center sm:justify-between sm:px-6 lg:px-8">
@page "/workflow-definitions/{WorkflowDefinitionVersionId}/designer"
<div class="flex-0 border-b border-gray-200 px-4 pt-4 sm:flex sm:items-start sm:justify-between sm:px-6 lg:px-8">
<div class="flex-1 min-w-0">
<h1 class="text-lg font-medium leading-6 text-gray-900 sm:truncate">
Workflow Definition Editor
@DisplayName
</h1>
<p class="mt-1 text-sm text-gray-600">
Workflow Definition
</p>
<div class="mt-6">
<nav class="-mb-px flex space-x-8" aria-label="Tabs">
@foreach (var item in Tabs)
{
var isCurrent = item == CurrentTab;
var cssClass = isCurrent ? "border-blue-500 text-gray-900" : "border-transparent text-gray-500 hover:text-gray-700 hover:border-gray-300";
<a @onclick:preventDefault @onclick="@(() => SelectTab(item))" href="#" class="@cssClass whitespace-nowrap py-4 px-1 border-b-2 font-medium text-sm" aria-current="page">
@item.Text
</a>
}
</nav>
</div>
</div>
<div class="mt-4 flex sm:mt-0 sm:ml-4">
<span class="order-0 sm:order-1 sm:ml-3 shadow-sm rounded-md">
@ -14,4 +29,17 @@
</span>
</div>
</div>
<WorkflowDesigner Model="WorkflowModel" WorkflowChanged="@OnWorkflowChanged" />
@if (CurrentTab.Name == "Designer")
{
<WorkflowDesigner Model="WorkflowModel" WorkflowChanged="@OnWorkflowChanged"/>
}
else if (CurrentTab.Name == "Dsl")
{
<div class="p-10">
</div>
}
else if (CurrentTab.Name == "Settings")
{
<Settings WorkflowDefinition="@WorkflowDefinition" OnChanged="@OnSettingsChanged" />
}

View file

@ -12,14 +12,24 @@ namespace ElsaDashboard.Application.Pages.WorkflowDefinitions
{
partial class Designer
{
[Parameter] public string? WorkflowDefinitionId { get; set; }
[Parameter] public string? WorkflowDefinitionVersionId { get; set; }
[Inject] private IWorkflowDefinitionService WorkflowDefinitionService { get; set; } = default!;
[Inject] private IActivityService ActivityService { get; set; } = default!;
[Inject] private NavigationManager NavigationManager { get; set; } = default!;
private IDictionary<string, ActivityInfo> ActivityDescriptors { get; set; } = default!;
private WorkflowDefinition WorkflowDefinition { get; set; } = default!;
private WorkflowDefinition WorkflowDefinition { get; set; } = new()
{
Name = "Untitled",
DisplayName = "Untitled",
Version = 1
};
private WorkflowModel WorkflowModel { get; set; } = WorkflowModel.Blank();
private BackgroundWorker BackgroundWorker { get; } = new();
private string DisplayName => !string.IsNullOrWhiteSpace(WorkflowDefinition.DisplayName) ? WorkflowDefinition.DisplayName : !string.IsNullOrWhiteSpace(WorkflowDefinition.Name) ? WorkflowDefinition.Name : "Untitled";
private static TabItem[] Tabs => new[] {new TabItem("Designer"), new TabItem("DSL", "Dsl"), new TabItem("Settings")};
private TabItem CurrentTab { get; set; } = Tabs.First();
protected override async Task OnInitializedAsync()
{
@ -29,9 +39,9 @@ namespace ElsaDashboard.Application.Pages.WorkflowDefinitions
protected override async Task OnParametersSetAsync()
{
if (WorkflowDefinitionId != null)
if (WorkflowDefinitionVersionId != null)
{
WorkflowDefinition = await WorkflowDefinitionService.GetByIdAsync(WorkflowDefinitionId, VersionOptions.Latest);
WorkflowDefinition = await WorkflowDefinitionService.GetByVersionIdAsync(WorkflowDefinitionVersionId);
WorkflowModel = CreateWorkflowModel(WorkflowDefinition);
}
else
@ -45,7 +55,7 @@ namespace ElsaDashboard.Application.Pages.WorkflowDefinitions
{
var request = new SaveWorkflowDefinitionRequest
{
WorkflowDefinitionId = WorkflowDefinition.WorkflowDefinitionId,
WorkflowDefinitionId = WorkflowDefinition.Id,
Activities = WorkflowModel.Activities.Select(CreateActivityDefinition).ToList(),
Connections = WorkflowModel.Connections.Select(x => new ConnectionDefinition(x.SourceId, x.TargetId, x.Outcome)).ToList(),
Name = WorkflowDefinition.Name,
@ -60,11 +70,11 @@ namespace ElsaDashboard.Application.Pages.WorkflowDefinitions
DeleteCompletedInstances = WorkflowDefinition.DeleteCompletedInstances
};
var isNew = WorkflowDefinition.WorkflowDefinitionId == null!;
WorkflowDefinition = await WorkflowDefinitionService.SaveAsync(request);
var isNew = WorkflowDefinition.Id == null!;
var savedWorkflowDefinition = await WorkflowDefinitionService.SaveAsync(request);
if (isNew)
NavigationManager.NavigateTo($"workflows/{WorkflowDefinition.WorkflowDefinitionId}/designer");
if (isNew)
NavigationManager.NavigateTo($"workflow-definitions/{savedWorkflowDefinition.DefinitionVersionId}/designer");
}
private ActivityDefinition CreateActivityDefinition(ActivityModel activityModel)
@ -86,10 +96,7 @@ namespace ElsaDashboard.Application.Pages.WorkflowDefinitions
};
}
private ConnectionModel CreateConnectionModel(ConnectionDefinition connectionDefinition)
{
return new(connectionDefinition.SourceActivityId, connectionDefinition.TargetActivityId, connectionDefinition.Outcome);
}
private ConnectionModel CreateConnectionModel(ConnectionDefinition connectionDefinition) => new(connectionDefinition.SourceActivityId, connectionDefinition.TargetActivityId, connectionDefinition.Outcome);
private ActivityModel CreateActivityModel(ActivityDefinition activityDefinition)
{
@ -104,6 +111,11 @@ namespace ElsaDashboard.Application.Pages.WorkflowDefinitions
};
}
private void SelectTab(TabItem tab)
{
CurrentTab = tab;
}
private void StartBackgroundWorker()
{
#pragma warning disable 4014
@ -116,5 +128,10 @@ namespace ElsaDashboard.Application.Pages.WorkflowDefinitions
WorkflowModel = e.WorkflowModel;
await BackgroundWorker.ScheduleTask(SaveWorkflowAsync);
}
private async Task OnSettingsChanged()
{
await BackgroundWorker.ScheduleTask(SaveWorkflowAsync);
}
}
}

View file

@ -115,7 +115,7 @@
<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-definitions/{workflowDefinition.WorkflowDefinitionId}/designer")" class="truncate hover:text-gray-600">
<a href="@($"workflow-definitions/{workflowDefinition.DefinitionVersionId}/designer")" class="truncate hover:text-gray-600">
<span>@displayName</span>
</a>
</div>
@ -154,7 +154,7 @@
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-definitions/{workflowDefinition.WorkflowDefinitionVersionId}/designer")" 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">
<a href="@($"workflow-definitions/{workflowDefinition.DefinitionVersionId}/designer")" 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"/>

View file

@ -0,0 +1,43 @@
<div class="p-10 bg-gray-100">
<div class="space-y-6 sm:px-6 lg:px-0 lg:col-span-9">
<section aria-labelledby="payment_details_heading">
<EditForm EditContext="@EditContext">
<div class="shadow sm:rounded-md sm:overflow-hidden">
<div class="bg-white py-6 px-4 sm:p-6">
<div>
<h2 id="payment_details_heading" class="text-lg leading-6 font-medium text-gray-900">General</h2>
<p class="mt-1 text-sm text-gray-500">General workflow settings.</p>
</div>
<div class="mt-6 grid grid-cols-4 gap-6">
<div class="col-span-4 sm:col-span-2">
<label for="workflowName" class="block text-sm font-medium text-gray-700">Name</label>
<InputText @bind-Value="@WorkflowDefinition.Name" type="text" id="workflowName" class="mt-1 block w-full border border-gray-300 rounded-md shadow-sm py-2 px-3 focus:outline-none sm:text-sm"/>
<p class="mt-2 text-sm text-gray-500">
The technical name of the workflow. Use this to programmatically reference your workflows or from other activities.
</p>
</div>
<div class="col-span-4 sm:col-span-2">
<label for="workflowDisplayName" class="block text-sm font-medium text-gray-700">Display Name</label>
<InputText @bind-Value="@WorkflowDefinition.DisplayName" type="text" id="workflowDisplayName" class="mt-1 block w-full border border-gray-300 rounded-md shadow-sm py-2 px-3 focus:outline-none sm:text-sm"/>
<p class="mt-2 text-sm text-gray-500">
Enter a human-friendly name.
</p>
</div>
<div class="col-span-4 sm:col-span-4">
<label for="workflowDescription" class="block text-sm font-medium text-gray-700">Description</label>
<InputTextArea @bind-Value="@WorkflowDefinition.Description" id="workflowDescription" class="mt-1 block w-full border border-gray-300 rounded-md shadow-sm py-2 px-3 focus:outline-none sm:text-sm"/>
<p class="mt-2 text-sm text-gray-500">
Enter a brief description about the function of your workflow.
</p>
</div>
</div>
</div>
</div>
</EditForm>
</section>
</div>
</div>

View file

@ -0,0 +1,21 @@
using Elsa.Client.Models;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Forms;
namespace ElsaDashboard.Application.Pages.WorkflowDefinitions
{
partial class Settings
{
[Parameter] public WorkflowDefinition WorkflowDefinition { private get; set; } = default!;
[Parameter] public EventCallback OnChanged { private get; set; }
private EditContext EditContext { get; set; } = default!;
protected override void OnInitialized()
{
EditContext = new EditContext(WorkflowDefinition);
EditContext.OnFieldChanged += OnFieldChanged;
}
private async void OnFieldChanged(object? sender, FieldChangedEventArgs e) => await OnChanged.InvokeAsync();
}
}

View file

@ -21,7 +21,7 @@
<path fill-rule="evenodd" clip-rule="evenodd" d="M8 4a4 4 0 100 8 4 4 0 000-8zM2 8a6 6 0 1110.89 3.476l4.817 4.817a1 1 0 01-1.414 1.414l-4.816-4.816A6 6 0 012 8z"></path>
</svg>
</div>
<InputText @bind-Value="@SearchModel.SearchTerm" id="search_field" class="block w-full h-full pl-8 pr-3 py-2 rounded-md text-cool-gray-900 placeholder-cool-gray-500 focus:outline-none focus:placeholder-cool-gray-400 sm:text-sm" placeholder="Search" type="search"/>
<InputText @bind-Value="@SearchModel.SearchTerm" id="search_field" class="block w-full h-full pl-8 pr-3 py-2 rounded-md text-cool-gray-900 placeholder-cool-gray-500 focus:outline-none focus:placeholder-cool-gray-400 sm:text-sm border-0" placeholder="Search" type="search"/>
</div>
</EditForm>
</div>

View file

@ -31,11 +31,11 @@
class="z-10 mx-3 origin-top-left absolute -right-48 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>
<a @onclick:preventDefault @onclick="@OnEditClick" 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">Delete</a>
<a @onclick:preventDefault @onclick="@OnDeleteClick" 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">Delete</a>
</div>
</div>
</div>

View file

@ -10,6 +10,8 @@ namespace ElsaDashboard.Application.Shared
public const string DefaultIconClass = "h-10 w-10 text-blue-500";
[Parameter] public ActivityModel Model { get; set; } = new();
[Parameter] public EventCallback<MouseEventArgs> OnClick { get; set; }
[Parameter] public EventCallback OnEditClick { get; set; }
[Parameter] public EventCallback OnDeleteClick { get; set; }
[Parameter] public RenderFragment Body { get; set; } = default!;
[Parameter] public RenderFragment Icon { get; set; } = default!;

View file

@ -9,7 +9,6 @@
<div id="workflow-canvas" class="flex-1 flex">
<div class="flex-1 text-gray-200">
<div class="p-10">
<div class="canvas select-none">
<div class="tree">
<ul>

View file

@ -21,7 +21,7 @@ namespace ElsaDashboard.Application.Shared
partial class WorkflowDesigner : IAsyncDisposable
{
private static Func<ConnectionModel, Task> _connectionCreatedAction = default!;
[Parameter] public WorkflowModel Model { private get; set; } = WorkflowModel.Blank();
[Parameter] public EventCallback<WorkflowModelChangedEventArgs> WorkflowChanged { get; set; }
[Inject] private IJSRuntime JS { get; set; } = default!;
@ -200,7 +200,7 @@ namespace ElsaDashboard.Application.Shared
if (existingConnection != null)
{
model = model with {Connections = model.Connections.Remove(existingConnection)};
var replacementConnection = existingConnection with { SourceId = activity.ActivityId};
var replacementConnection = existingConnection with {SourceId = activity.ActivityId};
model.AddConnection(replacementConnection);
}
else
@ -216,7 +216,7 @@ namespace ElsaDashboard.Application.Shared
if (existingConnection != null)
{
model = model with {Connections = model.Connections.Remove(existingConnection)};
var replacementConnection = existingConnection with { TargetId = activity.ActivityId};
var replacementConnection = existingConnection with {TargetId = activity.ActivityId};
model = model.AddConnection(replacementConnection);
var connection = new ConnectionModel(activity.ActivityId, existingConnection.TargetId, outcome);
@ -232,7 +232,7 @@ namespace ElsaDashboard.Application.Shared
await UpdateModelAsync(model);
await FlyoutPanelService.HideAsync();
}
private RenderFragment RenderActivity(ActivityModel activityModel)
{
return builder =>
@ -240,20 +240,21 @@ namespace ElsaDashboard.Application.Shared
var index = 0;
builder.OpenComponent<Activity>(index++);
builder.AddAttribute(index++, "Model", activityModel);
builder.AddAttribute(index++, "OnDeleteClick", EventCallbackFactory.Create(this, () => OnActivityDelete(activityModel)));
var displayDescriptor = activityModel.DisplayDescriptor;
if (displayDescriptor != null)
{
var context = new ActivityDisplayContext(activityModel.Type, activityModel.Properties);
if(displayDescriptor.RenderBody != null)
if (displayDescriptor.RenderBody != null)
builder.AddAttribute(index++, "Body", displayDescriptor.RenderBody(context));
if(displayDescriptor.RenderIcon != null)
if (displayDescriptor.RenderIcon != null)
builder.AddAttribute(index, "Icon", displayDescriptor.RenderIcon(context));
}
builder.CloseComponent();
};
}
@ -276,15 +277,9 @@ namespace ElsaDashboard.Application.Shared
ButtonDescriptor.Create("Cancel", _ => ShowActivityPickerAsync(sourceActivityId, targetActivityId, outcome)),
ButtonDescriptor.Create("OK", _ => AddActivityAsync(activityInfo, sourceActivityId, targetActivityId, outcome), true));
}
private async ValueTask OnActivityClick(MouseEventArgs e)
{
await FlyoutPanelService.ShowAsync<ActivityEditor>("Timer Properties");
}
private async Task OnConnectionCreatedAsync(ConnectionModel connection)
{
await UpdateModelAsync(Model.AddConnection(connection));
}
private async Task OnActivityDelete(ActivityModel activityModel) => await UpdateModelAsync(Model.RemoveActivity(activityModel));
private async ValueTask OnActivityClick(MouseEventArgs e) => await FlyoutPanelService.ShowAsync<ActivityEditor>("Timer Properties");
private async Task OnConnectionCreatedAsync(ConnectionModel connection) => await UpdateModelAsync(Model.AddConnection(connection));
}
}

View file

@ -1,4 +1,6 @@
using Elsa.Models;
using System;
using System.Linq.Expressions;
using Elsa.Models;
using Elsa.Persistence.YesSql.Documents;
using Elsa.Persistence.YesSql.Indexes;
using YesSql;

View file

@ -115,5 +115,6 @@ namespace Elsa.Persistence.YesSql.Stores
protected IQuery<TDocument> Query() => Session.Query<TDocument>(CollectionName);
protected IQuery<TDocument, TIndex> Query<TIndex>(Expression<Func<TIndex, bool>> predicate) where TIndex : class, IIndex => Session.Query<TDocument, TIndex>(predicate, CollectionName);
protected IQuery<TDocument, TIndex> Query<TIndex>() where TIndex : class, IIndex => Session.Query<TDocument, TIndex>(CollectionName);
}
}

View file

@ -5,6 +5,7 @@ using Elsa.Data;
using Elsa.Models;
using Elsa.Persistence.Specifications;
using Elsa.Persistence.YesSql.Documents;
using Elsa.Persistence.YesSql.Extensions;
using Elsa.Persistence.YesSql.Indexes;
using YesSql;
using IIdGenerator = Elsa.Services.IIdGenerator;
@ -21,10 +22,13 @@ namespace Elsa.Persistence.YesSql.Stores
protected override IQuery<WorkflowDefinitionDocument> MapSpecification(ISpecification<WorkflowDefinition> specification)
{
if (specification is EntityIdSpecification<WorkflowDefinition> entityIdSpecification)
return Query<WorkflowDefinitionIndex>(x => x.DefinitionId == entityIdSpecification.Id);
return AutoMapSpecification<WorkflowDefinitionIndex>(specification);
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),
_ => AutoMapSpecification<WorkflowDefinitionIndex>(specification)
};
}
protected override IQuery<WorkflowDefinitionDocument> OrderBy(IQuery<WorkflowDefinitionDocument> query, IOrderBy<WorkflowDefinition> orderBy, ISpecification<WorkflowDefinition> specification)

View file

@ -63,7 +63,7 @@ namespace Elsa.Server.Api.Endpoints.WorkflowDefinitions
else
workflowDefinition = await _workflowPublisher.SaveDraftAsync(workflowDefinition, cancellationToken);
return CreatedAtAction("Handle", "GetByVersionId", new {workflowDefinitionVersionId = workflowDefinition.DefinitionVersionId, apiVersion = apiVersion.ToString()}, workflowDefinition);
return CreatedAtAction("Handle", "GetByVersionId", new {versionId = workflowDefinition.DefinitionVersionId, apiVersion = apiVersion.ToString()}, workflowDefinition);
}
}
}

View file

@ -1,48 +0,0 @@
// using System.Collections.Generic;
// using System.Runtime.Serialization;
// using Elsa.Comparers;
// using Elsa.Models;
// using Newtonsoft.Json.Linq;
// using NodaTime;
//
// namespace Elsa.Server.Api.Models
// {
// [DataContract]
// public class WorkflowInstanceModel
// {
// private HashSet<BlockingActivity> _blockingActivities = new(BlockingActivityEqualityComparer.Instance);
//
// public WorkflowInstanceModel()
// {
// Variables = new Variables();
// Activities = new List<ActivityInstance>();
// ScheduledActivities = new Stack<ScheduledActivity>();
// PostScheduledActivities = new Stack<ScheduledActivity>();
// }
//
// [DataMember(Order = 1)] public string WorkflowInstanceId { get; set; } = default!;
// [DataMember(Order = 2)] public string WorkflowDefinitionId { get; set; } = default!;
// [DataMember(Order = 3)] public int Version { get; set; }
// [DataMember(Order = 4)] public WorkflowStatus Status { get; set; }
// [DataMember(Order = 5)] public string? CorrelationId { get; set; }
// [DataMember(Order = 6)] public string? ContextId { get; set; }
// [DataMember(Order = 7)] public string? Name { get; set; }
// [DataMember(Order = 8)] public Instant CreatedAt { get; set; }
// [DataMember(Order = 9)] public Instant? LastExecutedAt { get; set; }
// [DataMember(Order = 10)] public Instant? LastBurstAt { get; set; }
// [DataMember(Order = 11)] public Instant? CompletedAt { get; set; }
// [DataMember(Order = 12)] public Variables Variables { get; set; }
// [DataMember(Order = 13)] public JObject? Output { get; set; }
// [DataMember(Order = 14)] public ICollection<ActivityInstance> Activities { get; set; }
//
// [DataMember(Order = 15)] public HashSet<BlockingActivity> BlockingActivities
// {
// get => _blockingActivities;
// set => _blockingActivities = new HashSet<BlockingActivity>(value, BlockingActivityEqualityComparer.Instance);
// }
//
// [DataMember(Order = 16)] public WorkflowFault? Fault { get; set; }
// [DataMember(Order = 17)] public Stack<ScheduledActivity> ScheduledActivities { get; set; }
// [DataMember(Order = 18)] public Stack<ScheduledActivity> PostScheduledActivities { get; set; }
// }
// }