Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
0f439c1
Enhance flowchart handling and improve performance
maxcompyl Apr 24, 2025
d0058e1
Merge branch 'elsa-workflows:main' into main
MaxBrooks114 Apr 24, 2025
fa8480f
Merge branch 'main' into MethodNotSupportedOnJournalEntrySelect
MaxBrooks114 Apr 24, 2025
f26072c
Enhance flowchart handling and activity selection logic
maxcompyl Apr 24, 2025
84b8ca5
Merge branch 'MethodNotSupportedOnJournalEntrySelect' of https://gith…
maxcompyl Apr 24, 2025
df6d679
Merge branch 'main' of https://github.com/MaxBrooks114/elsa-studio in…
maxcompyl May 5, 2025
b6bebfa
can autolayout workflowinstance
maxcompyl May 8, 2025
337d842
Improve code readability and formatting
maxcompyl May 8, 2025
6e6a96d
Fix ability to reach nested activties in deisgner with programmatic w…
maxcompyl May 13, 2025
be59f66
Enhance graph interactivity and layout handling
maxcompyl May 15, 2025
d20f5cc
Merge branch 'main' into MovableNodesOnReadOnly
MaxBrooks114 May 19, 2025
07f0990
Merge branch 'main' into MovableNodesOnReadOnly
MaxBrooks114 May 22, 2025
7d7ee55
Merge branch 'main' into MovableNodesOnReadOnly
MaxBrooks114 May 27, 2025
102a5f1
update latest
maxcompyl Jun 2, 2025
07e2ec9
sync
maxcompyl Jun 6, 2025
3749f1e
dev merge fix
maxcompyl Jun 6, 2025
3b2c2d4
Merge branch 'main' of https://github.com/MaxBrooks114/elsa-studio in…
maxcompyl Jun 9, 2025
f64442e
Update Directory.Build.targets
MaxBrooks114 Jun 11, 2025
41878d4
Merge branch 'main' into MovableNodesOnReadOnly
MaxBrooks114 Jul 2, 2025
7d79d3c
Merge branch 'main' into MovableNodesOnReadOnly
MaxBrooks114 Jul 22, 2025
e145e51
Merge branch 'main' into MovableNodesOnReadOnly
KnibbsyMan Oct 5, 2025
ca948c7
Delete Directory.Build.targets
KnibbsyMan Oct 5, 2025
74e6fdb
Merge branch 'main' into MovableNodesOnReadOnly
sfmskywalker Dec 19, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -17,17 +17,57 @@ public class DefaultActivityResolver : IActivityResolver
public bool GetSupportsActivity(JsonObject activity) => true;

/// <inheritdoc />
public ValueTask<IEnumerable<EmbeddedActivity>> GetActivitiesAsync(JsonObject activity, CancellationToken cancellationToken = default)
public ValueTask<IEnumerable<EmbeddedActivity>> 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<EmbeddedActivity>();

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<JsonObject>())
{
// 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<JsonObject>())
embedded.Add(new EmbeddedActivity(child, propName));
}
}

return new ValueTask<IEnumerable<EmbeddedActivity>>(embedded);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -37,13 +37,13 @@ export async function createGraph(containerId: string, componentRef: DotNetCompo
maxScale: 3,
},
interacting: {
nodeMovable: () => !readOnly,
nodeMovable: () => true,
arrowheadMovable: () => !readOnly,
edgeMovable: () => !readOnly,
vertexMovable: () => !readOnly,
edgeMovable: () => true,
vertexMovable: () => true,
vertexAddable: () => !readOnly,
vertexDeletable: () => !readOnly,
edgeLabelMovable: () => !readOnly,
edgeLabelMovable: () => true,
magnetConnectable: () => !readOnly,
toolsAddable: () => !readOnly,
useEdgeTools: () => !readOnly,
Expand Down Expand Up @@ -135,9 +135,10 @@ export async function createGraph(containerId: string, componentRef: DotNetCompo
rubberEdge: false,
rubberNode: true,
rubberband: true,
movable: !readOnly,
movable: true,
showNodeSelectionBox: true,
className: 'elsa-selection'

}),
);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -370,6 +370,10 @@ protected override async Task OnAfterRenderAsync(bool firstRender)
_componentRef = DotNetObjectReference.Create(this);
_graphApi = await DesignerJsInterop.CreateGraphAsync(_containerId, _componentRef, IsReadOnly);
await _pendingGraphActions.ProcessAsync();
if (IsReadOnly && AllNodesAtOrigin(Flowchart))
{
await AutoLayoutAsync(Flowchart, ActivityStats);
}
}
}

Expand Down Expand Up @@ -472,4 +476,34 @@ void IDisposable.Dispose()
ThemeService.IsDarkModeChanged -= OnDarkModeChanged;
_componentRef?.Dispose();
}

private bool AllNodesAtOrigin(JsonObject flowchart)
{
var activities = flowchart.GetActivities(); // extension that pulls the “activities” array
foreach (var activity in activities)
{
// drill into metadata.designer.position.{x,y}
if (
activity.TryGetPropertyValue("metadata", out var metaNode)
&& metaNode is JsonObject meta
&& meta.TryGetPropertyValue("designer", out var designerNode)
&& designerNode is JsonObject designer
&& designer.TryGetPropertyValue("position", out var posNode)
&& posNode is JsonObject pos
)
{
var x = pos["x"]?.GetValue<double>() ?? 0;
var y = pos["y"]?.GetValue<double>() ?? 0;
if (x != 0 || y != 0)
return false;
}
else
{
// no metadata or no position? treat that as “still at origin”
continue;
}
}

return true;
}
}
Loading