| | | 1 | | using Elsa.Abstractions; |
| | | 2 | | using Elsa.Extensions; |
| | | 3 | | using Elsa.Workflows.Activities; |
| | | 4 | | using Elsa.Workflows.Activities.Flowchart.Activities; |
| | | 5 | | using Elsa.Workflows.Api.Models; |
| | | 6 | | using Elsa.Workflows.Management; |
| | | 7 | | using Elsa.Workflows.Serialization.Converters; |
| | | 8 | | using Elsa.Workflows.Serialization.Helpers; |
| | | 9 | | using JetBrains.Annotations; |
| | | 10 | | using Microsoft.AspNetCore.Http; |
| | | 11 | | |
| | | 12 | | namespace Elsa.Workflows.Api.Endpoints.WorkflowDefinitions.Graph.Segments; |
| | | 13 | | |
| | | 14 | | [PublicAPI] |
| | 1 | 15 | | internal class Nodes(IWorkflowDefinitionService workflowDefinitionService, IApiSerializer apiSerializer, ActivityWriter |
| | | 16 | | { |
| | | 17 | | public override void Configure() |
| | | 18 | | { |
| | 1 | 19 | | Get("/workflow-definitions/subgraph/segments/{id}"); |
| | 1 | 20 | | ConfigurePermissions("read:workflow-definitions"); |
| | 1 | 21 | | } |
| | | 22 | | |
| | | 23 | | public override async Task HandleAsync(Request request, CancellationToken cancellationToken) |
| | | 24 | | { |
| | 0 | 25 | | var workflowGraph = await workflowDefinitionService.FindWorkflowGraphAsync(request.Id, cancellationToken); |
| | | 26 | | |
| | 0 | 27 | | if (workflowGraph?.Root == null) |
| | | 28 | | { |
| | 0 | 29 | | await Send.NotFoundAsync(cancellationToken); |
| | 0 | 30 | | return; |
| | | 31 | | } |
| | | 32 | | |
| | 0 | 33 | | var nodeId = request.ChildNodeId; |
| | | 34 | | |
| | 0 | 35 | | if (!workflowGraph.NodeIdLookup.TryGetValue(nodeId, out var childNode)) |
| | | 36 | | { |
| | 0 | 37 | | AddError("Unknown node ID"); |
| | 0 | 38 | | await Send.ErrorsAsync(cancellation: cancellationToken); |
| | 0 | 39 | | return; |
| | | 40 | | } |
| | | 41 | | |
| | 0 | 42 | | var ancestors = childNode.Ancestors().ToList(); |
| | 0 | 43 | | var serializerOptions = apiSerializer.GetOptions().Clone().WithConverters(new RootActivityNodeConverter(activity |
| | 0 | 44 | | var segments = new Stack<ActivityPathSegment>(); |
| | 0 | 45 | | var currentNode = ancestors.FirstOrDefault(); |
| | 0 | 46 | | var previousNode = childNode; |
| | | 47 | | |
| | 0 | 48 | | while (currentNode != null) |
| | | 49 | | { |
| | 0 | 50 | | if (currentNode.Activity is not Workflow and not Flowchart) |
| | | 51 | | { |
| | 0 | 52 | | var currentActivity = currentNode.Activity; |
| | 0 | 53 | | var currentPort = previousNode.Port; |
| | 0 | 54 | | var activityName = currentActivity.Name ?? currentActivity.Type; |
| | 0 | 55 | | var segment = new ActivityPathSegment(currentNode.NodeId, currentActivity.Id, currentActivity.Type, curr |
| | 0 | 56 | | segments.Push(segment); |
| | | 57 | | } |
| | | 58 | | |
| | 0 | 59 | | previousNode = currentNode; |
| | 0 | 60 | | currentNode = currentNode.Parents.FirstOrDefault(); |
| | | 61 | | } |
| | | 62 | | |
| | 0 | 63 | | var leafSegment = segments.LastOrDefault(); |
| | 0 | 64 | | var container = leafSegment == null ? ancestors.LastOrDefault() ?? childNode : ancestors.Last(x => x.Activity.Id |
| | 0 | 65 | | var response = new Response(childNode, container, segments.ToList()); |
| | 0 | 66 | | await HttpContext.Response.WriteAsJsonAsync(response, serializerOptions, cancellationToken); |
| | 0 | 67 | | } |
| | | 68 | | } |