diff --git a/src/clients/Elsa.Api.Client/Extensions/JsonObjectExtensions.cs b/src/clients/Elsa.Api.Client/Extensions/JsonObjectExtensions.cs
index b65fcf394..b37f0f742 100644
--- a/src/clients/Elsa.Api.Client/Extensions/JsonObjectExtensions.cs
+++ b/src/clients/Elsa.Api.Client/Extensions/JsonObjectExtensions.cs
@@ -24,7 +24,7 @@ public static class JsonObjectExtensions
/// A representing the specified value.
public static JsonNode SerializeToNode(this object value, JsonSerializerOptions? options = null)
{
- options ??= new JsonSerializerOptions { PropertyNamingPolicy = JsonNamingPolicy.CamelCase };
+ options ??= new() { PropertyNamingPolicy = JsonNamingPolicy.CamelCase };
return JsonSerializer.SerializeToNode(value, options)!;
}
@@ -37,7 +37,7 @@ public static class JsonObjectExtensions
/// A representing the specified value.
public static JsonArray SerializeToArray(this object value, JsonSerializerOptions? options = null)
{
- options ??= new JsonSerializerOptions { PropertyNamingPolicy = JsonNamingPolicy.CamelCase };
+ options ??= new() { PropertyNamingPolicy = JsonNamingPolicy.CamelCase };
return JsonSerializer.SerializeToNode(value, options)!.AsArray();
}
@@ -50,7 +50,7 @@ public static class JsonObjectExtensions
/// A representing the specified value.
public static JsonArray SerializeToArray(this IEnumerable value, JsonSerializerOptions? options = null)
{
- options ??= new JsonSerializerOptions { PropertyNamingPolicy = JsonNamingPolicy.CamelCase };
+ options ??= new() { PropertyNamingPolicy = JsonNamingPolicy.CamelCase };
return JsonSerializer.SerializeToNode(value, options)!.AsArray();
}
diff --git a/src/clients/Elsa.Api.Client/Shared/Models/ActivityDesignerMetadata.cs b/src/clients/Elsa.Api.Client/Shared/Models/ActivityDesignerMetadata.cs
index 24e3f6d62..09a401099 100644
--- a/src/clients/Elsa.Api.Client/Shared/Models/ActivityDesignerMetadata.cs
+++ b/src/clients/Elsa.Api.Client/Shared/Models/ActivityDesignerMetadata.cs
@@ -23,7 +23,7 @@ public class ActivityDesignerMetadata
/// The y coordinate of the activity.
/// The width of the activity.
/// The height of the activity.
- public ActivityDesignerMetadata(double x, double y, double width, double height) : this(new Position(x, y), new Size(width, height))
+ public ActivityDesignerMetadata(double x, double y, double width, double height) : this(new(x, y), new(width, height))
{
}
diff --git a/src/clients/Elsa.Api.Client/Shared/Models/Connection.cs b/src/clients/Elsa.Api.Client/Shared/Models/Connection.cs
index 6794fb948..632786351 100644
--- a/src/clients/Elsa.Api.Client/Shared/Models/Connection.cs
+++ b/src/clients/Elsa.Api.Client/Shared/Models/Connection.cs
@@ -8,10 +8,15 @@ public class Connection
///
/// Gets or sets the source endpoint.
///
- public Endpoint Source { get; set; } = default!;
+ public Endpoint Source { get; set; } = null!;
///
/// Gets or sets the target endpoint.
///
- public Endpoint Target { get; set; } = default!;
+ public Endpoint Target { get; set; } = null!;
+
+ ///
+ /// Gets or sets the vertices of the connection.
+ ///
+ public ICollection Vertices { get; set; } = [];
}
\ No newline at end of file
diff --git a/src/modules/Elsa.Workflows.Core/Activities/Flowchart/Activities/Flowchart.cs b/src/modules/Elsa.Workflows.Core/Activities/Flowchart/Activities/Flowchart.cs
index 5fbe321b1..03e333b32 100644
--- a/src/modules/Elsa.Workflows.Core/Activities/Flowchart/Activities/Flowchart.cs
+++ b/src/modules/Elsa.Workflows.Core/Activities/Flowchart/Activities/Flowchart.cs
@@ -1,134 +1,134 @@
-using System.ComponentModel;
-using System.Runtime.CompilerServices;
-using Elsa.Extensions;
-using Elsa.Workflows.Activities.Flowchart.Contracts;
-using Elsa.Workflows.Activities.Flowchart.Models;
-using Elsa.Workflows.Attributes;
-using Elsa.Workflows.Options;
-using Elsa.Workflows.Signals;
-
-namespace Elsa.Workflows.Activities.Flowchart.Activities;
-
-///
-/// A flowchart consists of a collection of activities and connections between them.
-///
-[Activity("Elsa", "Flow", "A flowchart is a collection of activities and connections between them.")]
-[Browsable(false)]
-public class Flowchart : Container
-{
+using System.ComponentModel;
+using System.Runtime.CompilerServices;
+using Elsa.Extensions;
+using Elsa.Workflows.Activities.Flowchart.Contracts;
+using Elsa.Workflows.Activities.Flowchart.Models;
+using Elsa.Workflows.Attributes;
+using Elsa.Workflows.Options;
+using Elsa.Workflows.Signals;
+
+namespace Elsa.Workflows.Activities.Flowchart.Activities;
+
+///
+/// A flowchart consists of a collection of activities and connections between them.
+///
+[Activity("Elsa", "Flow", "A flowchart is a collection of activities and connections between them.")]
+[Browsable(false)]
+public class Flowchart : Container
+{
private const string ScopeProperty = "FlowScope";
private const string GraphTransientProperty = "FlowGraph";
private const string BackwardConnectionActivityInput = "BackwardConnection";
-
- ///
- public Flowchart([CallerFilePath] string? source = default, [CallerLineNumber] int? line = default) : base(source, line)
- {
- OnSignalReceived(OnScheduleOutcomesAsync);
- OnSignalReceived(OnScheduleChildActivityAsync);
- OnSignalReceived(OnActivityCanceledAsync);
- }
-
- ///
- /// The activity to execute when the flowchart starts.
- ///
- [Port] [Browsable(false)] public IActivity? Start { get; set; }
-
- ///
- /// A list of connections between activities.
- ///
- public ICollection Connections { get; set; } = new List();
-
- ///
- protected override async ValueTask ScheduleChildrenAsync(ActivityExecutionContext context)
- {
- var startActivity = GetStartActivity(context);
-
- if (startActivity == null)
- {
- // Nothing else to execute.
- await context.CompleteActivityAsync();
- return;
- }
-
- // Schedule the start activity.
- await context.ScheduleActivityAsync(startActivity, OnChildCompletedAsync);
- }
-
- private IActivity? GetStartActivity(ActivityExecutionContext context)
- {
- // If there's a trigger that triggered this workflow, use that.
- var triggerActivityId = context.WorkflowExecutionContext.TriggerActivityId;
- var triggerActivity = triggerActivityId != null ? Activities.FirstOrDefault(x => x.Id == triggerActivityId) : default;
-
- if (triggerActivity != null)
- return triggerActivity;
-
- // If an explicit Start activity was provided, use that.
- if (Start != null)
- return Start;
-
- // If there is a Start activity on the flowchart, use that.
- var startActivity = Activities.FirstOrDefault(x => x is Start);
-
- if (startActivity != null)
- return startActivity;
-
- // If there's an activity marked as "Can Start Workflow", use that.
- var canStartWorkflowActivity = Activities.FirstOrDefault(x => x.GetCanStartWorkflow());
-
- if (canStartWorkflowActivity != null)
- return canStartWorkflowActivity;
-
- // If there is a single activity that has no inbound connections, use that.
- var root = GetRootActivity();
-
- if (root != null)
- return root;
-
- // If no start activity found, return the first activity.
- return Activities.FirstOrDefault();
- }
- ///
- /// Checks if there is any pending work for the flowchart.
- ///
- private bool HasPendingWork(ActivityExecutionContext context)
- {
- var workflowExecutionContext = context.WorkflowExecutionContext;
- var activityIds = Activities.Select(x => x.Id).ToList();
- var children = context.Children;
- var hasRunningActivityInstances = children.Where(x => activityIds.Contains(x.Activity.Id)).Any(x => x.Status == ActivityStatus.Running);
-
- var hasPendingWork = workflowExecutionContext.Scheduler.List().Any(workItem =>
- {
- var ownerInstanceId = workItem.Owner?.Id;
-
- if (ownerInstanceId == null)
- return false;
-
- if (ownerInstanceId == context.Id)
- return true;
-
- var ownerContext = context.WorkflowExecutionContext.ActivityExecutionContexts.First(x => x.Id == ownerInstanceId);
- var ancestors = ownerContext.GetAncestors().ToList();
-
- return ancestors.Any(x => x == context);
- });
-
- return hasRunningActivityInstances || hasPendingWork;
- }
-
- private IActivity? GetRootActivity()
- {
- // Get the first activity that has no inbound connections.
- var query =
- from activity in Activities
- let inboundConnections = Connections.Any(x => x.Target.Activity == activity)
- where !inboundConnections
- select activity;
-
- var rootActivity = query.FirstOrDefault();
- return rootActivity;
+ ///
+ public Flowchart([CallerFilePath] string? source = null, [CallerLineNumber] int? line = null) : base(source, line)
+ {
+ OnSignalReceived(OnScheduleOutcomesAsync);
+ OnSignalReceived(OnScheduleChildActivityAsync);
+ OnSignalReceived(OnActivityCanceledAsync);
+ }
+
+ ///
+ /// The activity to execute when the flowchart starts.
+ ///
+ [Port] [Browsable(false)] public IActivity? Start { get; set; }
+
+ ///
+ /// A list of connections between activities.
+ ///
+ public ICollection Connections { get; set; } = new List();
+
+ ///
+ protected override async ValueTask ScheduleChildrenAsync(ActivityExecutionContext context)
+ {
+ var startActivity = GetStartActivity(context);
+
+ if (startActivity == null)
+ {
+ // Nothing else to execute.
+ await context.CompleteActivityAsync();
+ return;
+ }
+
+ // Schedule the start activity.
+ await context.ScheduleActivityAsync(startActivity, OnChildCompletedAsync);
+ }
+
+ private IActivity? GetStartActivity(ActivityExecutionContext context)
+ {
+ // If there's a trigger that triggered this workflow, use that.
+ var triggerActivityId = context.WorkflowExecutionContext.TriggerActivityId;
+ var triggerActivity = triggerActivityId != null ? Activities.FirstOrDefault(x => x.Id == triggerActivityId) : null;
+
+ if (triggerActivity != null)
+ return triggerActivity;
+
+ // If an explicit Start activity was provided, use that.
+ if (Start != null)
+ return Start;
+
+ // If there is a Start activity on the flowchart, use that.
+ var startActivity = Activities.FirstOrDefault(x => x is Start);
+
+ if (startActivity != null)
+ return startActivity;
+
+ // If there's an activity marked as "Can Start Workflow", use that.
+ var canStartWorkflowActivity = Activities.FirstOrDefault(x => x.GetCanStartWorkflow());
+
+ if (canStartWorkflowActivity != null)
+ return canStartWorkflowActivity;
+
+ // If there is a single activity that has no inbound connections, use that.
+ var root = GetRootActivity();
+
+ if (root != null)
+ return root;
+
+ // If no start activity found, return the first activity.
+ return Activities.FirstOrDefault();
+ }
+
+ ///
+ /// Checks if there is any pending work for the flowchart.
+ ///
+ private bool HasPendingWork(ActivityExecutionContext context)
+ {
+ var workflowExecutionContext = context.WorkflowExecutionContext;
+ var activityIds = Activities.Select(x => x.Id).ToList();
+ var children = context.Children;
+ var hasRunningActivityInstances = children.Where(x => activityIds.Contains(x.Activity.Id)).Any(x => x.Status == ActivityStatus.Running);
+
+ var hasPendingWork = workflowExecutionContext.Scheduler.List().Any(workItem =>
+ {
+ var ownerInstanceId = workItem.Owner?.Id;
+
+ if (ownerInstanceId == null)
+ return false;
+
+ if (ownerInstanceId == context.Id)
+ return true;
+
+ var ownerContext = context.WorkflowExecutionContext.ActivityExecutionContexts.First(x => x.Id == ownerInstanceId);
+ var ancestors = ownerContext.GetAncestors().ToList();
+
+ return ancestors.Any(x => x == context);
+ });
+
+ return hasRunningActivityInstances || hasPendingWork;
+ }
+
+ private IActivity? GetRootActivity()
+ {
+ // Get the first activity that has no inbound connections.
+ var query =
+ from activity in Activities
+ let inboundConnections = Connections.Any(x => x.Target.Activity == activity)
+ where !inboundConnections
+ select activity;
+
+ var rootActivity = query.FirstOrDefault();
+ return rootActivity;
}
private FlowGraph GetFlowGraph(ActivityExecutionContext context)
@@ -142,16 +142,16 @@ public class Flowchart : Container
return context.GetProperty(ScopeProperty, () => new FlowScope());
}
- private async ValueTask OnChildCompletedAsync(ActivityCompletedContext context)
+ private async ValueTask OnChildCompletedAsync(ActivityCompletedContext context)
{
var flowchartContext = context.TargetContext;
var completedActivityContext = context.ChildContext;
var completedActivity = completedActivityContext.Activity;
var result = context.Result;
- if (flowchartContext.Activity != this)
- {
- throw new Exception("Target context activity must be this flowchart");
+ if (flowchartContext.Activity != this)
+ {
+ throw new Exception("Target context activity must be this flowchart");
}
// If the completed activity's status is anything but "Completed", do not schedule its outbound activities.
@@ -174,13 +174,13 @@ public class Flowchart : Container
var flowGraph = GetFlowGraph(flowchartContext);
var flowScope = GetFlowScope(flowchartContext);
var completedActivityExcecutedByBackwardConnection = completedActivityContext.ActivityInput.GetValueOrDefault(BackwardConnectionActivityInput);
- bool hasScheduledActivity = await ScheduleOutboundActivitiesAsync(flowGraph, flowScope, flowchartContext, completedActivity, outcomes, completedActivityExcecutedByBackwardConnection);
+ bool hasScheduledActivity = await ScheduleOutboundActivitiesAsync(flowGraph, flowScope, flowchartContext, completedActivity, outcomes, completedActivityExcecutedByBackwardConnection);
// If there are not any outbound connections, complete the flowchart activity if there is no other pending work
if (!hasScheduledActivity)
{
await CompleteIfNoPendingWorkAsync(flowchartContext);
- }
+ }
}
///
@@ -355,65 +355,65 @@ public class Flowchart : Container
await activityExecutionContext.CancelActivityAsync();
}
}
-
- private async Task CompleteIfNoPendingWorkAsync(ActivityExecutionContext context)
- {
- var hasPendingWork = HasPendingWork(context);
-
- if (!hasPendingWork)
- {
- var hasFaultedActivities = context.Children.Any(x => x.Status == ActivityStatus.Faulted);
-
- if (!hasFaultedActivities)
- {
- await context.CompleteActivityAsync();
- }
- }
- }
-
- private async ValueTask OnScheduleOutcomesAsync(ScheduleActivityOutcomes signal, SignalContext context)
- {
- var flowchartContext = context.ReceiverActivityExecutionContext;
- var schedulingActivityContext = context.SenderActivityExecutionContext;
- var schedulingActivity = schedulingActivityContext.Activity;
- var outcomes = signal.Outcomes;
- var outboundConnections = Connections.Where(connection => connection.Source.Activity == schedulingActivity && outcomes.Contains(connection.Source.Port!)).ToList();
- var outboundActivities = outboundConnections.Select(x => x.Target.Activity).ToList();
-
- if (outboundActivities.Any())
- {
- // Schedule each child.
- foreach (var activity in outboundActivities) await flowchartContext.ScheduleActivityAsync(activity, OnChildCompletedAsync);
- }
- }
-
- private async ValueTask OnScheduleChildActivityAsync(ScheduleChildActivity signal, SignalContext context)
- {
- var flowchartContext = context.ReceiverActivityExecutionContext;
- var activity = signal.Activity;
- var activityExecutionContext = signal.ActivityExecutionContext;
-
- if (activityExecutionContext != null)
- {
- await flowchartContext.ScheduleActivityAsync(activityExecutionContext.Activity, new ScheduleWorkOptions
- {
- ExistingActivityExecutionContext = activityExecutionContext,
- CompletionCallback = OnChildCompletedAsync,
- Input = signal.Input
- });
- }
- else
- {
- await flowchartContext.ScheduleActivityAsync(activity, new ScheduleWorkOptions
- {
- CompletionCallback = OnChildCompletedAsync,
- Input = signal.Input
- });
- }
- }
-
- private async ValueTask OnActivityCanceledAsync(CancelSignal signal, SignalContext context)
- {
- await CompleteIfNoPendingWorkAsync(context.ReceiverActivityExecutionContext);
- }
+
+ private async Task CompleteIfNoPendingWorkAsync(ActivityExecutionContext context)
+ {
+ var hasPendingWork = HasPendingWork(context);
+
+ if (!hasPendingWork)
+ {
+ var hasFaultedActivities = context.Children.Any(x => x.Status == ActivityStatus.Faulted);
+
+ if (!hasFaultedActivities)
+ {
+ await context.CompleteActivityAsync();
+ }
+ }
+ }
+
+ private async ValueTask OnScheduleOutcomesAsync(ScheduleActivityOutcomes signal, SignalContext context)
+ {
+ var flowchartContext = context.ReceiverActivityExecutionContext;
+ var schedulingActivityContext = context.SenderActivityExecutionContext;
+ var schedulingActivity = schedulingActivityContext.Activity;
+ var outcomes = signal.Outcomes;
+ var outboundConnections = Connections.Where(connection => connection.Source.Activity == schedulingActivity && outcomes.Contains(connection.Source.Port!)).ToList();
+ var outboundActivities = outboundConnections.Select(x => x.Target.Activity).ToList();
+
+ if (outboundActivities.Any())
+ {
+ // Schedule each child.
+ foreach (var activity in outboundActivities) await flowchartContext.ScheduleActivityAsync(activity, OnChildCompletedAsync);
+ }
+ }
+
+ private async ValueTask OnScheduleChildActivityAsync(ScheduleChildActivity signal, SignalContext context)
+ {
+ var flowchartContext = context.ReceiverActivityExecutionContext;
+ var activity = signal.Activity;
+ var activityExecutionContext = signal.ActivityExecutionContext;
+
+ if (activityExecutionContext != null)
+ {
+ await flowchartContext.ScheduleActivityAsync(activityExecutionContext.Activity, new ScheduleWorkOptions
+ {
+ ExistingActivityExecutionContext = activityExecutionContext,
+ CompletionCallback = OnChildCompletedAsync,
+ Input = signal.Input
+ });
+ }
+ else
+ {
+ await flowchartContext.ScheduleActivityAsync(activity, new ScheduleWorkOptions
+ {
+ CompletionCallback = OnChildCompletedAsync,
+ Input = signal.Input
+ });
+ }
+ }
+
+ private async ValueTask OnActivityCanceledAsync(CancelSignal signal, SignalContext context)
+ {
+ await CompleteIfNoPendingWorkAsync(context.ReceiverActivityExecutionContext);
+ }
}
\ No newline at end of file
diff --git a/src/modules/Elsa.Workflows.Core/Activities/Flowchart/Models/Connection.cs b/src/modules/Elsa.Workflows.Core/Activities/Flowchart/Models/Connection.cs
index 698e3bf3d..8b5c1e281 100644
--- a/src/modules/Elsa.Workflows.Core/Activities/Flowchart/Models/Connection.cs
+++ b/src/modules/Elsa.Workflows.Core/Activities/Flowchart/Models/Connection.cs
@@ -33,25 +33,30 @@ public class Connection : IEquatable
/// The target endpoint.
public Connection(IActivity source, IActivity target)
{
- Source = new Endpoint(source);
- Target = new Endpoint(target);
+ Source = new(source);
+ Target = new(target);
}
///
/// The source endpoint.
///
- public Endpoint Source { get; set; } = default!;
+ public Endpoint Source { get; set; } = null!;
///
/// The target endpoint.
///
- public Endpoint Target { get; set; } = default!;
-
- public override string ToString() =>
- $"{Source.Activity.Id}{(string.IsNullOrEmpty(Source.Port) ? "" : $":{Source.Port}")}->" +
- $"{Target.Activity.Id}{(string.IsNullOrEmpty(Target.Port) ? "" : $":{Target.Port}")}";
-
- // Implement equality logic
+ public Endpoint Target { get; set; } = null!;
+
+ ///
+ /// A collection of points representing the vertices of the connection.
+ ///
+ public ICollection Vertices { get; set; } = [];
+
+ public override string ToString() =>
+ $"{Source.Activity.Id}{(string.IsNullOrEmpty(Source.Port) ? "" : $":{Source.Port}")}->" +
+ $"{Target.Activity.Id}{(string.IsNullOrEmpty(Target.Port) ? "" : $":{Target.Port}")}";
+
+ // Implement equality logic
public bool Equals(Connection? other)
{
if (other == null) return false;
@@ -72,7 +77,7 @@ public class Connection : IEquatable
{
return e1.Activity.Equals(e2.Activity) && e1.Port == e2.Port;
}
-
+
private static int GetEndpointHashCode(Endpoint endpoint)
{
return HashCode.Combine(endpoint.Activity.GetHashCode(), endpoint.Port?.GetHashCode() ?? 0);
diff --git a/src/modules/Elsa.Workflows.Core/Activities/Flowchart/Models/Position.cs b/src/modules/Elsa.Workflows.Core/Activities/Flowchart/Models/Position.cs
new file mode 100644
index 000000000..215e0cf2d
--- /dev/null
+++ b/src/modules/Elsa.Workflows.Core/Activities/Flowchart/Models/Position.cs
@@ -0,0 +1,10 @@
+using JetBrains.Annotations;
+
+namespace Elsa.Workflows.Activities.Flowchart.Models;
+
+[UsedImplicitly]
+public class Position
+{
+ public double X { get; set; }
+ public double Y { get; set; }
+}
\ No newline at end of file
diff --git a/src/modules/Elsa.Workflows.Core/Activities/Flowchart/Serialization/ConnectionJsonConverter.cs b/src/modules/Elsa.Workflows.Core/Activities/Flowchart/Serialization/ConnectionJsonConverter.cs
index bdd00ee17..6c4656b1c 100644
--- a/src/modules/Elsa.Workflows.Core/Activities/Flowchart/Serialization/ConnectionJsonConverter.cs
+++ b/src/modules/Elsa.Workflows.Core/Activities/Flowchart/Serialization/ConnectionJsonConverter.cs
@@ -29,15 +29,23 @@ public class ConnectionJsonConverter : JsonConverter
var sourceElement = doc.RootElement.GetProperty("source");
var targetElement = doc.RootElement.GetProperty("target");
var sourceId = sourceElement.GetProperty("activity").GetString()!;
- var targetId = targetElement.TryGetProperty("activity", out var targetIdValue) ? targetIdValue.GetString() : default;
- var sourcePort = sourceElement.TryGetProperty("port", out var sourcePortValue) ? sourcePortValue.GetString() : default;
- var targetPort = targetElement.TryGetProperty("port", out var targetPortValue) ? targetPortValue.GetString() : default;
-
- var sourceActivity = _activities.TryGetValue(sourceId, out var s) ? s : default!;
- var targetActivity = targetId != null ? _activities.TryGetValue(targetId, out var t) ? t : default! : default!;
+ var targetId = targetElement.TryGetProperty("activity", out var targetIdValue) ? targetIdValue.GetString() : null;
+ var sourcePort = sourceElement.TryGetProperty("port", out var sourcePortValue) ? sourcePortValue.GetString() : null;
+ var targetPort = targetElement.TryGetProperty("port", out var targetPortValue) ? targetPortValue.GetString() : null;
+ var sourceActivity = _activities.TryGetValue(sourceId, out var s) ? s : null!;
+ var targetActivity = targetId != null ? _activities.TryGetValue(targetId, out var t) ? t : null! : null!;
var source = new Endpoint(sourceActivity, sourcePort);
var target = new Endpoint(targetActivity, targetPort);
- return new Connection(source, target);
+ var verticesElement = doc.RootElement.TryGetProperty("vertices", out var verticesValue) ? verticesValue : default;
+ var vertices = Array.Empty();
+
+ if (verticesElement.ValueKind == JsonValueKind.Array)
+ vertices = verticesElement.Deserialize(options)!;
+
+ return new(source, target)
+ {
+ Vertices = vertices
+ };
}
///
@@ -57,7 +65,8 @@ public class ConnectionJsonConverter : JsonConverter
{
Activity = value.Target.Activity.Id,
Port = value.Target.Port
- }
+ },
+ Vertices = value.Vertices
};
JsonSerializer.Serialize(writer, model, options);
diff --git a/src/modules/Elsa.Workflows.Core/Activities/Flowchart/Serialization/FlowchartJsonConverter.cs b/src/modules/Elsa.Workflows.Core/Activities/Flowchart/Serialization/FlowchartJsonConverter.cs
index 827630a42..c2bded0d4 100644
--- a/src/modules/Elsa.Workflows.Core/Activities/Flowchart/Serialization/FlowchartJsonConverter.cs
+++ b/src/modules/Elsa.Workflows.Core/Activities/Flowchart/Serialization/FlowchartJsonConverter.cs
@@ -24,9 +24,9 @@ public class FlowchartJsonConverter(IIdentityGenerator identityGenerator, IWellK
throw new JsonException("Failed to parse JsonDocument");
var id = doc.RootElement.TryGetProperty("id", out var idAttribute) ? idAttribute.GetString()! : identityGenerator.GenerateId();
- var nodeId = doc.RootElement.TryGetProperty("nodeId", out var nodeIdAttribute) ? nodeIdAttribute.GetString() : default;
- var name = doc.RootElement.TryGetProperty("name", out var nameElement) ? nameElement.GetString() : default;
- var type = doc.RootElement.TryGetProperty("type", out var typeElement) ? typeElement.GetString() : default;
+ var nodeId = doc.RootElement.TryGetProperty("nodeId", out var nodeIdAttribute) ? nodeIdAttribute.GetString() : null;
+ var name = doc.RootElement.TryGetProperty("name", out var nameElement) ? nameElement.GetString() : null;
+ var type = doc.RootElement.TryGetProperty("type", out var typeElement) ? typeElement.GetString() : null;
var version = doc.RootElement.TryGetProperty("version", out var versionElement) ? versionElement.GetInt32() : 1;
var connectionsElement = doc.RootElement.TryGetProperty("connections", out var connectionsEl) ? connectionsEl : default;
@@ -165,8 +165,8 @@ public class FlowchartJsonConverter(IIdentityGenerator identityGenerator, IWellK
connectionSerializerOptions.Converters.Add(new ObsoleteConnectionJsonConverter(activityDictionary));
var obsoleteConnections = connectionsElement.ValueKind != JsonValueKind.Undefined
- ? connectionsElement.Deserialize>(connectionSerializerOptions)?.Where(x => x.Source != null! && x.Target != null!).ToList() ?? new List()
- : new List();
+ ? connectionsElement.Deserialize>(connectionSerializerOptions)?.Where(x => x.Source != null! && x.Target != null!).ToList() ?? []
+ : [];
return obsoleteConnections.Select(x => new Connection(new Endpoint(x.Source, x.SourcePort), new Endpoint(x.Target, x.TargetPort))).ToList();
}
@@ -174,7 +174,7 @@ public class FlowchartJsonConverter(IIdentityGenerator identityGenerator, IWellK
connectionSerializerOptions.Converters.Add(new ConnectionJsonConverter(activityDictionary));
return connectionsElement.ValueKind != JsonValueKind.Undefined
- ? connectionsElement.Deserialize>(connectionSerializerOptions)?.Where(x => x.Source != null! && x.Target != null!).ToList() ?? new List()
- : new List();
+ ? connectionsElement.Deserialize>(connectionSerializerOptions)?.Where(x => x.Source != null! && x.Target != null!).ToList() ?? []
+ : [];
}
}
\ No newline at end of file