diff --git a/src/modules/Elsa.Studio.Workflows.Core/Resolvers/DefaultActivityResolver.cs b/src/modules/Elsa.Studio.Workflows.Core/Resolvers/DefaultActivityResolver.cs index 2cbb070a7..6a147f663 100644 --- a/src/modules/Elsa.Studio.Workflows.Core/Resolvers/DefaultActivityResolver.cs +++ b/src/modules/Elsa.Studio.Workflows.Core/Resolvers/DefaultActivityResolver.cs @@ -1,4 +1,4 @@ -using System.Text.Json.Nodes; +using System.Text.Json.Nodes; using Elsa.Api.Client.Extensions; using Elsa.Studio.Workflows.Domain.Contracts; using Elsa.Studio.Workflows.Domain.Models; @@ -17,17 +17,57 @@ public class DefaultActivityResolver : IActivityResolver public bool GetSupportsActivity(JsonObject activity) => true; /// - public ValueTask> GetActivitiesAsync(JsonObject activity, CancellationToken cancellationToken = default) + public ValueTask> GetActivitiesAsync( + JsonObject activity, + CancellationToken cancellationToken = default + ) { - var containedActivities = - from prop in activity - where prop.Value is JsonObject jsonObject && jsonObject.IsActivity() || prop.Value is JsonArray - let isCollection = prop.Value is JsonArray - let containedItems = isCollection ? ((JsonArray)prop.Value).ToArray() : new[] { prop.Value.AsObject() } - from containedItem in containedItems where containedItem is JsonObject && containedItem.AsObject().IsActivity() - let containedObject = containedItem.AsObject() - select new EmbeddedActivity(containedObject, prop.Key); - - return new(containedActivities.ToList()); + var embedded = new List(); + + foreach (var (propName, node) in activity) + { + switch (node) + { + // 1) direct child activity: + case JsonObject childObj when childObj.IsActivity(): + embedded.Add(new EmbeddedActivity(childObj, propName)); + break; + + // 2) array of activities: + case JsonArray arr: + foreach (var item in arr.OfType()) + { + // e.g. expectedStatusCodes: pick up item.activity + if ( + item.TryGetPropertyValue("activity", out var actNode) + && actNode is JsonObject actObj + && actObj.IsActivity() + ) + { + embedded.Add(new EmbeddedActivity(actObj, propName)); + } + else if (item.IsActivity()) + { + embedded.Add(new EmbeddedActivity(item, propName)); + } + } + break; + } + + // 3) special‑case any nested Flowchart under "body": + if ( + node is JsonObject container + && container.TryGetPropertyValue("body", out var bodyNode) + && bodyNode is JsonObject bodyObj + && bodyObj.TryGetPropertyValue("activities", out var activitiesNode) + && activitiesNode is JsonArray childActivities + ) + { + foreach (var child in childActivities.OfType()) + embedded.Add(new EmbeddedActivity(child, propName)); + } + } + + return new ValueTask>(embedded); } -} \ No newline at end of file +} diff --git a/src/modules/Elsa.Studio.Workflows/Shared/Components/DiagramDesignerWrapper.razor.cs b/src/modules/Elsa.Studio.Workflows/Shared/Components/DiagramDesignerWrapper.razor.cs index 2b268ce94..2e7d57a6a 100644 --- a/src/modules/Elsa.Studio.Workflows/Shared/Components/DiagramDesignerWrapper.razor.cs +++ b/src/modules/Elsa.Studio.Workflows/Shared/Components/DiagramDesignerWrapper.razor.cs @@ -163,11 +163,9 @@ private async Task SelectActivityAsync(JsonObject? activityToSelect, string? nod if (nodeId == null) return; - // Load the selected node path from the backend. - var pathSegmentsResponse = await WorkflowDefinitionService.GetPathSegmentsAsync( - WorkflowDefinitionVersionId, - nodeId - ); + var pathSegmentsResponse = await WorkflowDefinitionService.GetPathSegmentsAsync(WorkflowDefinitionVersionId, nodeId); + + if (pathSegmentsResponse == null) return; @@ -469,7 +467,7 @@ private async Task DisplayCurrentSegmentAsync() private async Task OnActivityDoubleClick(JsonObject activity) { - if (!IsReadOnly) + if (IsReadOnly) return; // If the activity is a workflow definition activity, then open the workflow definition editor. @@ -528,6 +526,18 @@ await WorkflowDefinitionService.FindSubgraphAsync( if (embeddedActivity != null) { + + var childDescriptor = ActivityRegistry.Find( + embeddedActivity.GetTypeName(), + embeddedActivity.GetVersion() + )!; + var childPortContext = new PortProviderContext(childDescriptor, embeddedActivity); + var childPortProvider = ActivityPortService.GetProvider(childPortContext); + var childPorts = childPortProvider.GetPorts(childPortContext); + + // if it has _no_ ports, it�s just a leaf � show the property editor: + if (!childPorts.Any()) + var embeddedActivityTypeName = embeddedActivity.GetTypeName(); // If the embedded activity has no designer support, then open it in the activity properties editor by raising the ActivitySelected event. @@ -535,13 +545,13 @@ await WorkflowDefinitionService.FindSubgraphAsync( embeddedActivityTypeName != "Elsa.Flowchart" && embeddedActivityTypeName != "Elsa.Workflow" ) + { if (ActivitySelected.HasDelegate) await ActivitySelected.InvokeAsync(embeddedActivity); + return; } - - // If the embedded activity type is a flowchart or workflow, we can display it in the designer. } else {