Implement workflow settings
This commit is contained in:
parent
5f08df0556
commit
c6d68875c1
|
|
@ -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; }
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
@ -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"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ module.exports = {
|
|||
plugins: [
|
||||
require('@tailwindcss/ui')({
|
||||
layout: 'sidebar',
|
||||
})
|
||||
}),
|
||||
require('@tailwindcss/forms')
|
||||
],
|
||||
};
|
||||
|
|
|
|||
|
|
@ -0,0 +1,10 @@
|
|||
namespace ElsaDashboard.Application.Models
|
||||
{
|
||||
public record TabItem(string Text, string Name)
|
||||
{
|
||||
public TabItem(string text) : this(text, text)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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" />
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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"/>
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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!;
|
||||
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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; }
|
||||
// }
|
||||
// }
|
||||
Loading…
Reference in a new issue