Added custom connectors for array and list
Some checks failed
Build / build (push) Has been cancelled
Some checks failed
Build / build (push) Has been cancelled
This commit is contained in:
24
Examples/Nodify.Calculator/AssertOperationViewModel.cs
Normal file
24
Examples/Nodify.Calculator/AssertOperationViewModel.cs
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
namespace Nodify.Calculator
|
||||||
|
{
|
||||||
|
public class AssertOperationViewModel : SystemOperationViewModel
|
||||||
|
{
|
||||||
|
private string _assertType = "Equals";
|
||||||
|
public string AssertType
|
||||||
|
{
|
||||||
|
get => _assertType;
|
||||||
|
set => SetProperty(ref _assertType, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool? _lastResult;
|
||||||
|
public bool? LastResult
|
||||||
|
{
|
||||||
|
get => _lastResult;
|
||||||
|
set => SetProperty(ref _lastResult, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public AssertOperationViewModel()
|
||||||
|
{
|
||||||
|
SystemOperationType = SystemOperations.ASSERT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -11,6 +11,7 @@ namespace Nodify.Calculator
|
|||||||
Circle,
|
Circle,
|
||||||
Triangle,
|
Triangle,
|
||||||
Square,
|
Square,
|
||||||
|
Grid,
|
||||||
}
|
}
|
||||||
|
|
||||||
public class ConnectorViewModel : ObservableObject
|
public class ConnectorViewModel : ObservableObject
|
||||||
|
|||||||
@@ -129,6 +129,21 @@
|
|||||||
</Style>
|
</Style>
|
||||||
<SolidColorBrush x:Key="SquareConnectorColor" Color="MediumSlateBlue"></SolidColorBrush>
|
<SolidColorBrush x:Key="SquareConnectorColor" Color="MediumSlateBlue"></SolidColorBrush>
|
||||||
<SolidColorBrush x:Key="TriangleConnectorColor" Color="White"></SolidColorBrush>
|
<SolidColorBrush x:Key="TriangleConnectorColor" Color="White"></SolidColorBrush>
|
||||||
|
<SolidColorBrush x:Key="GridConnectorColor" Color="#4CAF50"></SolidColorBrush>
|
||||||
|
|
||||||
|
<ControlTemplate x:Key="GridConnector" TargetType="Control">
|
||||||
|
<Grid Width="14" Height="14">
|
||||||
|
<Ellipse Width="3" Height="3" Fill="{TemplateBinding BorderBrush}" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="1,1,0,0" />
|
||||||
|
<Ellipse Width="3" Height="3" Fill="{TemplateBinding BorderBrush}" HorizontalAlignment="Center" VerticalAlignment="Top" Margin="0,1,0,0" />
|
||||||
|
<Ellipse Width="3" Height="3" Fill="{TemplateBinding BorderBrush}" HorizontalAlignment="Right" VerticalAlignment="Top" Margin="0,1,1,0" />
|
||||||
|
<Ellipse Width="3" Height="3" Fill="{TemplateBinding BorderBrush}" HorizontalAlignment="Left" VerticalAlignment="Center" Margin="1,0,0,0" />
|
||||||
|
<Ellipse Width="3" Height="3" Fill="{TemplateBinding BorderBrush}" HorizontalAlignment="Center" VerticalAlignment="Center" />
|
||||||
|
<Ellipse Width="3" Height="3" Fill="{TemplateBinding BorderBrush}" HorizontalAlignment="Right" VerticalAlignment="Center" Margin="0,0,1,0" />
|
||||||
|
<Ellipse Width="3" Height="3" Fill="{TemplateBinding BorderBrush}" HorizontalAlignment="Left" VerticalAlignment="Bottom" Margin="1,0,0,1" />
|
||||||
|
<Ellipse Width="3" Height="3" Fill="{TemplateBinding BorderBrush}" HorizontalAlignment="Center" VerticalAlignment="Bottom" Margin="0,0,0,1" />
|
||||||
|
<Ellipse Width="3" Height="3" Fill="{TemplateBinding BorderBrush}" HorizontalAlignment="Right" VerticalAlignment="Bottom" Margin="0,0,1,1" />
|
||||||
|
</Grid>
|
||||||
|
</ControlTemplate>
|
||||||
<Style x:Key="ConnectionStyle" TargetType="{x:Type nodify:BaseConnection}">
|
<Style x:Key="ConnectionStyle" TargetType="{x:Type nodify:BaseConnection}">
|
||||||
<Style.Triggers>
|
<Style.Triggers>
|
||||||
<DataTrigger Binding="{Binding Input.Shape}"
|
<DataTrigger Binding="{Binding Input.Shape}"
|
||||||
@@ -139,6 +154,10 @@
|
|||||||
Value="{x:Static local:ConnectorShape.Triangle}">
|
Value="{x:Static local:ConnectorShape.Triangle}">
|
||||||
<Setter Property="Stroke" Value="{StaticResource TriangleConnectorColor}"></Setter>
|
<Setter Property="Stroke" Value="{StaticResource TriangleConnectorColor}"></Setter>
|
||||||
</DataTrigger>
|
</DataTrigger>
|
||||||
|
<DataTrigger Binding="{Binding Input.Shape}"
|
||||||
|
Value="{x:Static local:ConnectorShape.Grid}">
|
||||||
|
<Setter Property="Stroke" Value="{StaticResource GridConnectorColor}"></Setter>
|
||||||
|
</DataTrigger>
|
||||||
</Style.Triggers>
|
</Style.Triggers>
|
||||||
<Setter Property="Stroke" Value="{DynamicResource Connection.StrokeBrush}"></Setter>
|
<Setter Property="Stroke" Value="{DynamicResource Connection.StrokeBrush}"></Setter>
|
||||||
<Setter Property="Cursor" Value="Hand"></Setter>
|
<Setter Property="Cursor" Value="Hand"></Setter>
|
||||||
@@ -240,6 +259,11 @@
|
|||||||
Value="{x:Static local:ConnectorShape.Circle}">
|
Value="{x:Static local:ConnectorShape.Circle}">
|
||||||
<Setter Property="BorderBrush" Value="{Binding Color}"></Setter>
|
<Setter Property="BorderBrush" Value="{Binding Color}"></Setter>
|
||||||
</DataTrigger>
|
</DataTrigger>
|
||||||
|
<DataTrigger Binding="{Binding Shape}"
|
||||||
|
Value="{x:Static local:ConnectorShape.Grid}">
|
||||||
|
<Setter Property="ConnectorTemplate" Value="{StaticResource GridConnector}" />
|
||||||
|
<Setter Property="BorderBrush" Value="{StaticResource GridConnectorColor}"></Setter>
|
||||||
|
</DataTrigger>
|
||||||
</Style.Triggers>
|
</Style.Triggers>
|
||||||
</Style>
|
</Style>
|
||||||
|
|
||||||
@@ -288,6 +312,11 @@
|
|||||||
Value="{x:Static local:ConnectorShape.Circle}">
|
Value="{x:Static local:ConnectorShape.Circle}">
|
||||||
<Setter Property="BorderBrush" Value="{Binding Color}"></Setter>
|
<Setter Property="BorderBrush" Value="{Binding Color}"></Setter>
|
||||||
</DataTrigger>
|
</DataTrigger>
|
||||||
|
<DataTrigger Binding="{Binding Shape}"
|
||||||
|
Value="{x:Static local:ConnectorShape.Grid}">
|
||||||
|
<Setter Property="ConnectorTemplate" Value="{StaticResource GridConnector}" />
|
||||||
|
<Setter Property="BorderBrush" Value="{StaticResource GridConnectorColor}"></Setter>
|
||||||
|
</DataTrigger>
|
||||||
</Style.Triggers>
|
</Style.Triggers>
|
||||||
</Style>
|
</Style>
|
||||||
|
|
||||||
@@ -551,6 +580,55 @@
|
|||||||
</nodify:Node>
|
</nodify:Node>
|
||||||
</DataTemplate>
|
</DataTemplate>
|
||||||
|
|
||||||
|
<DataTemplate DataType="{x:Type local:ForEachOperationViewModel}">
|
||||||
|
<nodify:Node Input="{Binding Input}"
|
||||||
|
Output="{Binding Output}"
|
||||||
|
BorderBrush="#4CAF50"
|
||||||
|
BorderThickness="2">
|
||||||
|
<nodify:Node.Header>
|
||||||
|
<StackPanel Orientation="Horizontal">
|
||||||
|
<TextBlock Text="🔁"
|
||||||
|
FontSize="14"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Margin="0 0 6 0" />
|
||||||
|
<TextBlock Text="{Binding Title}"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
FontWeight="SemiBold" />
|
||||||
|
</StackPanel>
|
||||||
|
</nodify:Node.Header>
|
||||||
|
<TextBlock Text="Iterates over each item in a list"
|
||||||
|
FontSize="10"
|
||||||
|
Foreground="#4CAF50"
|
||||||
|
Opacity="0.8"
|
||||||
|
Margin="4 2" />
|
||||||
|
</nodify:Node>
|
||||||
|
</DataTemplate>
|
||||||
|
|
||||||
|
<DataTemplate DataType="{x:Type local:AssertOperationViewModel}">
|
||||||
|
<nodify:Node Input="{Binding Input}"
|
||||||
|
Output="{Binding Output}"
|
||||||
|
BorderBrush="#FF5722"
|
||||||
|
BorderThickness="2">
|
||||||
|
<nodify:Node.Header>
|
||||||
|
<StackPanel Orientation="Horizontal">
|
||||||
|
<TextBlock Text="✅"
|
||||||
|
FontSize="14"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Margin="0 0 6 0" />
|
||||||
|
<TextBlock Text="{Binding Title}"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
FontWeight="SemiBold" />
|
||||||
|
</StackPanel>
|
||||||
|
</nodify:Node.Header>
|
||||||
|
<StackPanel Margin="4 2">
|
||||||
|
<TextBlock Text="Compares Actual vs Expected"
|
||||||
|
FontSize="10"
|
||||||
|
Foreground="#FF5722"
|
||||||
|
Opacity="0.8" />
|
||||||
|
</StackPanel>
|
||||||
|
</nodify:Node>
|
||||||
|
</DataTemplate>
|
||||||
|
|
||||||
<DataTemplate DataType="{x:Type local:TakeOperationViewModel}">
|
<DataTemplate DataType="{x:Type local:TakeOperationViewModel}">
|
||||||
<nodify:Node Header="{Binding Title}"
|
<nodify:Node Header="{Binding Title}"
|
||||||
Content="{Binding}"
|
Content="{Binding}"
|
||||||
|
|||||||
@@ -502,6 +502,138 @@ namespace Nodify.Calculator
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Handle Assert nodes
|
||||||
|
if (op is AssertOperationViewModel assertSysOp)
|
||||||
|
{
|
||||||
|
OnLogMe?.Invoke($"[ASSERT] Evaluating assertion: {op.Title}");
|
||||||
|
string actualVal = "";
|
||||||
|
string expectedVal = "";
|
||||||
|
|
||||||
|
// Find "Actual" and "Expected" input values
|
||||||
|
foreach (var inp in op.Input)
|
||||||
|
{
|
||||||
|
if (inp.Shape == ConnectorShape.Triangle) continue;
|
||||||
|
var title = inp.Title?.Trim() ?? "";
|
||||||
|
|
||||||
|
// Check if there's a connection feeding this input
|
||||||
|
var inputCon = connections.FirstOrDefault(c => c.Input == inp);
|
||||||
|
string val = "";
|
||||||
|
if (inputCon != null)
|
||||||
|
{
|
||||||
|
var srcNodeId = inputCon.Output.Operation.NodeId;
|
||||||
|
if (outputs.TryGetValue(srcNodeId, out var srcVal))
|
||||||
|
val = srcVal;
|
||||||
|
else if (inputCon.Output.Value != null)
|
||||||
|
val = inputCon.Output.Value.ToString();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
val = inp.Value.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (title.StartsWith("Actual")) actualVal = val;
|
||||||
|
else if (title.StartsWith("Expected")) expectedVal = val;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool passed = string.Equals(actualVal?.Trim(), expectedVal?.Trim(), StringComparison.OrdinalIgnoreCase);
|
||||||
|
outputs[op.NodeId] = passed.ToString();
|
||||||
|
|
||||||
|
if (passed)
|
||||||
|
{
|
||||||
|
OnLogMe?.Invoke($"[ASSERT] ✅ PASSED — Actual: \"{actualVal}\" == Expected: \"{expectedVal}\"");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
OnLogMe?.Invoke($"[ASSERT] ❌ FAILED — Actual: \"{actualVal}\" != Expected: \"{expectedVal}\"", logType.Error);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle ForEach loop nodes
|
||||||
|
if (op is ForEachOperationViewModel forEachSysOp)
|
||||||
|
{
|
||||||
|
OnLogMe?.Invoke($"[FOREACH] Starting loop: {op.Title}");
|
||||||
|
|
||||||
|
// Get the list input value
|
||||||
|
string listJson = "";
|
||||||
|
var listInput = op.Input.FirstOrDefault(i => i.Shape != ConnectorShape.Triangle);
|
||||||
|
if (listInput != null)
|
||||||
|
{
|
||||||
|
var listCon = connections.FirstOrDefault(c => c.Input == listInput);
|
||||||
|
if (listCon != null)
|
||||||
|
{
|
||||||
|
var srcNodeId = listCon.Output.Operation.NodeId;
|
||||||
|
if (outputs.TryGetValue(srcNodeId, out var srcVal))
|
||||||
|
listJson = srcVal;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (string.IsNullOrEmpty(listJson))
|
||||||
|
{
|
||||||
|
OnLogMe?.Invoke($"[FOREACH] No list data found. Skipping loop.", logType.Warning);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse the list
|
||||||
|
Newtonsoft.Json.Linq.JArray array;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var token = Newtonsoft.Json.Linq.JToken.Parse(listJson);
|
||||||
|
if (token is Newtonsoft.Json.Linq.JArray arr)
|
||||||
|
array = arr;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
OnLogMe?.Invoke($"[FOREACH] Input is not an array. Wrapping as single-element array.", logType.Warning);
|
||||||
|
array = new Newtonsoft.Json.Linq.JArray(token);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
OnLogMe?.Invoke($"[FOREACH] Failed to parse input as JSON array.", logType.Error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find the "Loop Body" flow output connection and "Current Item"/"Index" data outputs
|
||||||
|
var loopBodyOutput = op.Output.FirstOrDefault(o => o.Title == "Loop Body");
|
||||||
|
var currentItemOutput = op.Output.FirstOrDefault(o => o.Title == "Current Item");
|
||||||
|
var indexOutput = op.Output.FirstOrDefault(o => o.Title == "Index");
|
||||||
|
|
||||||
|
var loopBodyConnection = loopBodyOutput != null
|
||||||
|
? connections.FirstOrDefault(c => c.Output == loopBodyOutput)
|
||||||
|
: null;
|
||||||
|
|
||||||
|
OnLogMe?.Invoke($"[FOREACH] Iterating over {array.Count} items...");
|
||||||
|
|
||||||
|
for (int i = 0; i < array.Count; i++)
|
||||||
|
{
|
||||||
|
var item = array[i];
|
||||||
|
var itemStr = item.ToString(Newtonsoft.Json.Formatting.None);
|
||||||
|
|
||||||
|
OnLogMe?.Invoke($"[FOREACH] Iteration {i}: {(itemStr.Length > 80 ? itemStr.Substring(0, 80) + "..." : itemStr)}");
|
||||||
|
|
||||||
|
// Set Current Item and Index output values
|
||||||
|
outputs[op.NodeId] = itemStr;
|
||||||
|
if (currentItemOutput != null)
|
||||||
|
currentItemOutput.Value = double.TryParse(itemStr, out var dv) ? dv : 0;
|
||||||
|
if (indexOutput != null)
|
||||||
|
indexOutput.Value = i;
|
||||||
|
|
||||||
|
// Execute the loop body chain if connected
|
||||||
|
if (loopBodyConnection != null)
|
||||||
|
{
|
||||||
|
var bodyNode = loopBodyConnection.Input?.Operation;
|
||||||
|
if (bodyNode != null)
|
||||||
|
{
|
||||||
|
var visited = new HashSet<string>();
|
||||||
|
TraverseChain(bodyNode, "end", connections, visited, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
OnLogMe?.Invoke($"[FOREACH] Loop completed. {array.Count} iterations executed.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Handle Function nodes — execute the inner flow
|
// Handle Function nodes — execute the inner flow
|
||||||
if (op is FunctionOperationViewModel funcOp)
|
if (op is FunctionOperationViewModel funcOp)
|
||||||
{
|
{
|
||||||
|
|||||||
10
Examples/Nodify.Calculator/ForEachOperationViewModel.cs
Normal file
10
Examples/Nodify.Calculator/ForEachOperationViewModel.cs
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
namespace Nodify.Calculator
|
||||||
|
{
|
||||||
|
public class ForEachOperationViewModel : SystemOperationViewModel
|
||||||
|
{
|
||||||
|
public ForEachOperationViewModel()
|
||||||
|
{
|
||||||
|
SystemOperationType = SystemOperations.FOREACH;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -117,6 +117,25 @@ namespace Nodify.Calculator
|
|||||||
};
|
};
|
||||||
newObjectNode.Input.Add("");
|
newObjectNode.Input.Add("");
|
||||||
|
|
||||||
|
var forEachNode = new OperationInfoViewModel()
|
||||||
|
{
|
||||||
|
Title = "ForEach",
|
||||||
|
Type = OperationType.System,
|
||||||
|
sysOp = SystemOperations.FOREACH,
|
||||||
|
IsFlowNode = true
|
||||||
|
};
|
||||||
|
forEachNode.Input.Add("List");
|
||||||
|
|
||||||
|
var assertNode = new OperationInfoViewModel()
|
||||||
|
{
|
||||||
|
Title = "Assert",
|
||||||
|
Type = OperationType.System,
|
||||||
|
sysOp = SystemOperations.ASSERT,
|
||||||
|
IsFlowNode = true
|
||||||
|
};
|
||||||
|
assertNode.Input.Add("Actual");
|
||||||
|
assertNode.Input.Add("Expected");
|
||||||
|
|
||||||
systemNodes.Add(authNode);
|
systemNodes.Add(authNode);
|
||||||
systemNodes.Add(copynode);
|
systemNodes.Add(copynode);
|
||||||
systemNodes.Add(debugNode);
|
systemNodes.Add(debugNode);
|
||||||
@@ -127,6 +146,8 @@ namespace Nodify.Calculator
|
|||||||
systemNodes.Add(jsonParseNode);
|
systemNodes.Add(jsonParseNode);
|
||||||
systemNodes.Add(splitNode);
|
systemNodes.Add(splitNode);
|
||||||
systemNodes.Add(takeNode);
|
systemNodes.Add(takeNode);
|
||||||
|
systemNodes.Add(forEachNode);
|
||||||
|
systemNodes.Add(assertNode);
|
||||||
return systemNodes;
|
return systemNodes;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -292,13 +313,13 @@ namespace Nodify.Calculator
|
|||||||
bool isList = responseClassName.StartsWith("List<") && responseClassName.EndsWith(">");
|
bool isList = responseClassName.StartsWith("List<") && responseClassName.EndsWith(">");
|
||||||
var innerType = isList ? responseClassName.Substring(5, responseClassName.Length - 6) : responseClassName;
|
var innerType = isList ? responseClassName.Substring(5, responseClassName.Length - 6) : responseClassName;
|
||||||
|
|
||||||
// Square connector for model output
|
// Use Grid shape for list/array types, Square for single model
|
||||||
_o.Output.Add(new ConnectorViewModel
|
_o.Output.Add(new ConnectorViewModel
|
||||||
{
|
{
|
||||||
Title = responseClassName,
|
Title = responseClassName,
|
||||||
IsInput = false,
|
IsInput = false,
|
||||||
Shape = ConnectorShape.Square,
|
Shape = isList ? ConnectorShape.Grid : ConnectorShape.Square,
|
||||||
ConnectorColor = Color.MediumPurple,
|
ConnectorColor = isList ? Color.MediumSpringGreen : Color.MediumPurple,
|
||||||
DataType = responseClassName
|
DataType = responseClassName
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -370,6 +391,79 @@ namespace Nodify.Calculator
|
|||||||
return newObjOp;
|
return newObjOp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (info.sysOp == SystemOperations.FOREACH)
|
||||||
|
{
|
||||||
|
var forEachOp = new ForEachOperationViewModel
|
||||||
|
{
|
||||||
|
Title = info.Title
|
||||||
|
};
|
||||||
|
// Flow connectors
|
||||||
|
forEachOp.Input.Add(new ConnectorViewModel { Title = "", Shape = ConnectorShape.Triangle });
|
||||||
|
forEachOp.Output.Add(new ConnectorViewModel { Title = "", Shape = ConnectorShape.Triangle, IsInput = false });
|
||||||
|
// List data input (Grid shape for array/list types)
|
||||||
|
forEachOp.Input.Add(new ConnectorViewModel
|
||||||
|
{
|
||||||
|
Title = "List",
|
||||||
|
Shape = ConnectorShape.Grid,
|
||||||
|
ConnectorColor = Color.MediumSpringGreen
|
||||||
|
});
|
||||||
|
// "Loop Body" flow output — connects to nodes executed per iteration
|
||||||
|
forEachOp.Output.Add(new ConnectorViewModel
|
||||||
|
{
|
||||||
|
Title = "Loop Body",
|
||||||
|
IsInput = false,
|
||||||
|
Shape = ConnectorShape.Triangle,
|
||||||
|
ConnectorColor = Color.MediumSpringGreen
|
||||||
|
});
|
||||||
|
// "Current Item" data output — the element of the current iteration
|
||||||
|
forEachOp.Output.Add(new ConnectorViewModel
|
||||||
|
{
|
||||||
|
Title = "Current Item",
|
||||||
|
IsInput = false,
|
||||||
|
Shape = ConnectorShape.Circle,
|
||||||
|
ConnectorColor = Color.MediumSpringGreen,
|
||||||
|
DataType = "object"
|
||||||
|
});
|
||||||
|
// "Index" data output — current iteration index
|
||||||
|
forEachOp.Output.Add(new ConnectorViewModel
|
||||||
|
{
|
||||||
|
Title = "Index",
|
||||||
|
IsInput = false,
|
||||||
|
Shape = ConnectorShape.Circle,
|
||||||
|
ConnectorColor = Color.LightSkyBlue,
|
||||||
|
DataType = "int"
|
||||||
|
});
|
||||||
|
return forEachOp;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (info.sysOp == SystemOperations.ASSERT)
|
||||||
|
{
|
||||||
|
var assertOp = new AssertOperationViewModel
|
||||||
|
{
|
||||||
|
Title = info.Title
|
||||||
|
};
|
||||||
|
// Flow connectors
|
||||||
|
assertOp.Input.Add(new ConnectorViewModel { Title = "", Shape = ConnectorShape.Triangle });
|
||||||
|
assertOp.Output.Add(new ConnectorViewModel { Title = "", Shape = ConnectorShape.Triangle, IsInput = false });
|
||||||
|
// Data inputs
|
||||||
|
foreach (var inp in input)
|
||||||
|
{
|
||||||
|
inp.ConnectorColor = Color.Gold;
|
||||||
|
inp.Shape = ConnectorShape.Circle;
|
||||||
|
assertOp.Input.Add(inp);
|
||||||
|
}
|
||||||
|
// "Result" output — pass/fail boolean
|
||||||
|
assertOp.Output.Add(new ConnectorViewModel
|
||||||
|
{
|
||||||
|
Title = "Result",
|
||||||
|
IsInput = false,
|
||||||
|
Shape = ConnectorShape.Circle,
|
||||||
|
ConnectorColor = Color.Gold,
|
||||||
|
DataType = "bool"
|
||||||
|
});
|
||||||
|
return assertOp;
|
||||||
|
}
|
||||||
|
|
||||||
if (info.sysOp == SystemOperations.DEBUG)
|
if (info.sysOp == SystemOperations.DEBUG)
|
||||||
{
|
{
|
||||||
var debugOp = new SystemOperationViewModel
|
var debugOp = new SystemOperationViewModel
|
||||||
|
|||||||
@@ -20,7 +20,9 @@ namespace Nodify.Calculator
|
|||||||
AUTH,
|
AUTH,
|
||||||
FUNCTION,
|
FUNCTION,
|
||||||
DEBUG,
|
DEBUG,
|
||||||
NEW_OBJECT
|
NEW_OBJECT,
|
||||||
|
FOREACH,
|
||||||
|
ASSERT
|
||||||
}
|
}
|
||||||
|
|
||||||
public class SystemOperationViewModel : OperationViewModel
|
public class SystemOperationViewModel : OperationViewModel
|
||||||
|
|||||||
Reference in New Issue
Block a user