Added function in the panel for user to be added new function
This commit is contained in:
97
Examples/Nodify.Calculator/CreateFunctionDialog.xaml
Normal file
97
Examples/Nodify.Calculator/CreateFunctionDialog.xaml
Normal file
@@ -0,0 +1,97 @@
|
||||
<Window x:Class="Nodify.Calculator.CreateFunctionDialog"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
Title="Create New Function"
|
||||
Width="500"
|
||||
Height="520"
|
||||
WindowStartupLocation="CenterOwner"
|
||||
ResizeMode="NoResize"
|
||||
Background="#2D2D30"
|
||||
Foreground="White">
|
||||
<Grid Margin="15">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="*" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="*" />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<!-- Function Name -->
|
||||
<TextBlock Text="Function Name:" Grid.Row="0" Margin="0 0 0 4" />
|
||||
<TextBox x:Name="FunctionNameBox" Grid.Row="1" Margin="0 0 0 10"
|
||||
Background="#3E3E42" Foreground="White" Padding="4" />
|
||||
|
||||
<!-- Input Parameters -->
|
||||
<StackPanel Orientation="Horizontal" Grid.Row="2" Margin="0 0 0 4">
|
||||
<TextBlock Text="Input Parameters:" FontWeight="Bold" />
|
||||
<Button Content="➕ Add" Margin="10 0 0 0" Padding="8 2" Click="AddInput_Click"
|
||||
Background="#3E3E42" Foreground="White" Cursor="Hand" />
|
||||
</StackPanel>
|
||||
<DataGrid x:Name="InputParamsGrid" Grid.Row="3" Margin="0 0 0 10"
|
||||
AutoGenerateColumns="False" CanUserAddRows="False" CanUserDeleteRows="True"
|
||||
Background="#3E3E42" Foreground="White" RowBackground="#3E3E42"
|
||||
AlternatingRowBackground="#333337" GridLinesVisibility="None"
|
||||
HeadersVisibility="Column" BorderBrush="#555">
|
||||
<DataGrid.Columns>
|
||||
<DataGridTextColumn Header="Name" Binding="{Binding Name}" Width="*" />
|
||||
<DataGridComboBoxColumn Header="Type" SelectedItemBinding="{Binding Type}" Width="120">
|
||||
<DataGridComboBoxColumn.ItemsSource>
|
||||
<x:Array Type="sys:String" xmlns:sys="clr-namespace:System;assembly=System.Runtime">
|
||||
<sys:String>string</sys:String>
|
||||
<sys:String>int</sys:String>
|
||||
<sys:String>double</sys:String>
|
||||
<sys:String>bool</sys:String>
|
||||
<sys:String>float</sys:String>
|
||||
<sys:String>decimal</sys:String>
|
||||
<sys:String>long</sys:String>
|
||||
<sys:String>DateTime</sys:String>
|
||||
<sys:String>object</sys:String>
|
||||
</x:Array>
|
||||
</DataGridComboBoxColumn.ItemsSource>
|
||||
</DataGridComboBoxColumn>
|
||||
</DataGrid.Columns>
|
||||
</DataGrid>
|
||||
|
||||
<!-- Output Parameters -->
|
||||
<StackPanel Orientation="Horizontal" Grid.Row="4" Margin="0 0 0 4">
|
||||
<TextBlock Text="Output Parameters:" FontWeight="Bold" />
|
||||
<Button Content="➕ Add" Margin="10 0 0 0" Padding="8 2" Click="AddOutput_Click"
|
||||
Background="#3E3E42" Foreground="White" Cursor="Hand" />
|
||||
</StackPanel>
|
||||
<DataGrid x:Name="OutputParamsGrid" Grid.Row="5" Margin="0 0 0 10"
|
||||
AutoGenerateColumns="False" CanUserAddRows="False" CanUserDeleteRows="True"
|
||||
Background="#3E3E42" Foreground="White" RowBackground="#3E3E42"
|
||||
AlternatingRowBackground="#333337" GridLinesVisibility="None"
|
||||
HeadersVisibility="Column" BorderBrush="#555">
|
||||
<DataGrid.Columns>
|
||||
<DataGridTextColumn Header="Name" Binding="{Binding Name}" Width="*" />
|
||||
<DataGridComboBoxColumn Header="Type" SelectedItemBinding="{Binding Type}" Width="120">
|
||||
<DataGridComboBoxColumn.ItemsSource>
|
||||
<x:Array Type="sys:String" xmlns:sys="clr-namespace:System;assembly=System.Runtime">
|
||||
<sys:String>string</sys:String>
|
||||
<sys:String>int</sys:String>
|
||||
<sys:String>double</sys:String>
|
||||
<sys:String>bool</sys:String>
|
||||
<sys:String>float</sys:String>
|
||||
<sys:String>decimal</sys:String>
|
||||
<sys:String>long</sys:String>
|
||||
<sys:String>DateTime</sys:String>
|
||||
<sys:String>object</sys:String>
|
||||
</x:Array>
|
||||
</DataGridComboBoxColumn.ItemsSource>
|
||||
</DataGridComboBoxColumn>
|
||||
</DataGrid.Columns>
|
||||
</DataGrid>
|
||||
|
||||
<!-- Buttons -->
|
||||
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right" Grid.Row="6">
|
||||
<Button Content="Create" Width="80" Margin="0 0 10 0" Padding="4"
|
||||
Click="OnCreateClick" IsDefault="True" />
|
||||
<Button Content="Cancel" Width="80" Padding="4"
|
||||
Click="OnCancelClick" IsCancel="True" />
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</Window>
|
||||
52
Examples/Nodify.Calculator/CreateFunctionDialog.xaml.cs
Normal file
52
Examples/Nodify.Calculator/CreateFunctionDialog.xaml.cs
Normal file
@@ -0,0 +1,52 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Windows;
|
||||
|
||||
namespace Nodify.Calculator
|
||||
{
|
||||
public partial class CreateFunctionDialog : Window
|
||||
{
|
||||
public string FunctionName { get; private set; } = string.Empty;
|
||||
public List<FunctionParameterInfo> InputParameters { get; } = new List<FunctionParameterInfo>();
|
||||
public List<FunctionParameterInfo> OutputParameters { get; } = new List<FunctionParameterInfo>();
|
||||
|
||||
private readonly ObservableCollection<FunctionParameterInfo> _inputs = new ObservableCollection<FunctionParameterInfo>();
|
||||
private readonly ObservableCollection<FunctionParameterInfo> _outputs = new ObservableCollection<FunctionParameterInfo>();
|
||||
|
||||
public CreateFunctionDialog()
|
||||
{
|
||||
InitializeComponent();
|
||||
InputParamsGrid.ItemsSource = _inputs;
|
||||
OutputParamsGrid.ItemsSource = _outputs;
|
||||
}
|
||||
|
||||
private void AddInput_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
_inputs.Add(new FunctionParameterInfo { Name = $"param{_inputs.Count + 1}", Type = "string" });
|
||||
}
|
||||
|
||||
private void AddOutput_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
_outputs.Add(new FunctionParameterInfo { Name = $"result{_outputs.Count + 1}", Type = "string" });
|
||||
}
|
||||
|
||||
private void OnCreateClick(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(FunctionNameBox.Text))
|
||||
{
|
||||
MessageBox.Show("Please enter a function name.", "Validation", MessageBoxButton.OK, MessageBoxImage.Warning);
|
||||
return;
|
||||
}
|
||||
|
||||
FunctionName = FunctionNameBox.Text.Trim();
|
||||
InputParameters.AddRange(_inputs);
|
||||
OutputParameters.AddRange(_outputs);
|
||||
DialogResult = true;
|
||||
}
|
||||
|
||||
private void OnCancelClick(object sender, RoutedEventArgs e)
|
||||
{
|
||||
DialogResult = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -433,6 +433,21 @@
|
||||
</nodify:Node>
|
||||
</DataTemplate>
|
||||
|
||||
<DataTemplate DataType="{x:Type local:FunctionOperationViewModel}">
|
||||
<nodify:Node Header="{Binding Title}"
|
||||
Input="{Binding Input}"
|
||||
Output="{Binding Output}"
|
||||
ToolTip="Double click to edit function"
|
||||
BorderBrush="#FF9800"
|
||||
BorderThickness="2">
|
||||
<nodify:Node.InputBindings>
|
||||
<MouseBinding Gesture="LeftDoubleClick"
|
||||
Command="{Binding DataContext.OpenCalculatorCommand, RelativeSource={RelativeSource AncestorType=UserControl}}"
|
||||
CommandParameter="{Binding InnerCalculator}" />
|
||||
</nodify:Node.InputBindings>
|
||||
</nodify:Node>
|
||||
</DataTemplate>
|
||||
|
||||
<DataTemplate DataType="{x:Type local:CalculatorOperationViewModel}">
|
||||
<nodify:Node Header="{Binding Title}"
|
||||
Input="{Binding Input}"
|
||||
@@ -691,6 +706,38 @@
|
||||
</DataTemplate>
|
||||
</ItemsControl.ItemTemplate>
|
||||
</ItemsControl>
|
||||
|
||||
<!-- Functions Section -->
|
||||
<TextBlock Text="Functions" FontWeight="Bold" Margin="0 8 0 4" />
|
||||
<Button Content="➕ Create New Function"
|
||||
Command="{Binding Calculator.OperationsMenu.CreateFunctionCommand}"
|
||||
Margin="0 0 0 6"
|
||||
Padding="6 3"
|
||||
Cursor="Hand"
|
||||
Background="#FF9800"
|
||||
Foreground="White" />
|
||||
<ItemsControl ItemsSource="{Binding Calculator.OperationsMenu.AvailableFunctions}"
|
||||
Focusable="False">
|
||||
<ItemsControl.ItemContainerStyle>
|
||||
<Style>
|
||||
<Setter Property="FrameworkElement.Margin" Value="3" />
|
||||
<Setter Property="FrameworkElement.HorizontalAlignment" Value="Left" />
|
||||
<Setter Property="FrameworkElement.Cursor" Value="Hand" />
|
||||
<Setter Property="FrameworkElement.ToolTip" Value="Drag and drop to add this function to the flow" />
|
||||
</Style>
|
||||
</ItemsControl.ItemContainerStyle>
|
||||
<ItemsControl.ItemTemplate>
|
||||
<DataTemplate DataType="{x:Type local:OperationInfoViewModel}">
|
||||
<Border Background="#3E3E42" CornerRadius="3" Padding="6 4"
|
||||
MouseMove="OnNodeDrag" Cursor="Hand">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<TextBlock Text="ƒ " Foreground="#FF9800" FontWeight="Bold" />
|
||||
<TextBlock Text="{Binding Title}" Foreground="Orange" FontWeight="SemiBold" />
|
||||
</StackPanel>
|
||||
</Border>
|
||||
</DataTemplate>
|
||||
</ItemsControl.ItemTemplate>
|
||||
</ItemsControl>
|
||||
</StackPanel>
|
||||
</ScrollViewer>
|
||||
</DockPanel>
|
||||
|
||||
@@ -428,6 +428,14 @@ namespace Nodify.Calculator
|
||||
OnLogMe?.Invoke($"Auth node resolved. Base URL: {_authBaseUrl}, Auth Type: {_authType}");
|
||||
return;
|
||||
}
|
||||
|
||||
// Handle Function nodes — execute the inner flow
|
||||
if (op is FunctionOperationViewModel funcOp)
|
||||
{
|
||||
OnLogMe?.Invoke($"Executing function: {funcOp.FunctionName}");
|
||||
ExecuteFunction(funcOp, connections);
|
||||
return;
|
||||
}
|
||||
OnLogMe?.Invoke($"Starting Execution : {url}");
|
||||
var res = GetResponse(url, "get");
|
||||
if (!string.IsNullOrEmpty(res))
|
||||
@@ -509,16 +517,83 @@ namespace Nodify.Calculator
|
||||
|
||||
private static string GetConnectorTextValue(ConnectorViewModel connector)
|
||||
{
|
||||
// When the connector is not connected, the user enters text in the Value text box.
|
||||
// Value is a double, so we try to use it as a string representation.
|
||||
// However, for string inputs (URL, token, etc.) the value won't be meaningful as a double.
|
||||
// The user-typed string is actually stored in the Title field for unconnected inputs in some cases,
|
||||
// but here we rely on the ConnectorViewModel.Value being 0 (default) and the actual string
|
||||
// is not captured as double. So we return empty — the AuthOperationViewModel properties are the
|
||||
// primary source set via the node's text boxes.
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
private void ExecuteFunction(FunctionOperationViewModel funcOp, ICollection<ConnectionViewModel> connections)
|
||||
{
|
||||
// Propagate outer input values into the function
|
||||
for (int i = 0; i < funcOp.InputParameters.Count; i++)
|
||||
{
|
||||
var outerInputIndex = i + 1; // skip flow triangle
|
||||
if (outerInputIndex < funcOp.Input.Count)
|
||||
{
|
||||
var outerConnector = funcOp.Input[outerInputIndex];
|
||||
var inputCon = connections.FirstOrDefault(c => c.Input == outerConnector);
|
||||
if (inputCon != null)
|
||||
{
|
||||
var sourceNodeId = inputCon.Output.Operation.NodeId;
|
||||
if (outputs.TryGetValue(sourceNodeId, out var val))
|
||||
{
|
||||
outerConnector.Value = double.TryParse(val, out var d) ? d : 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Trigger propagation of input values to inner Begin node
|
||||
funcOp.PropagateInputsToInner();
|
||||
|
||||
// Execute the inner calculator's flow (Begin -> End)
|
||||
var innerOps = funcOp.InnerCalculator.Operations;
|
||||
var innerConns = funcOp.InnerCalculator.Connections;
|
||||
|
||||
OnLogMe?.Invoke($" [Function '{funcOp.FunctionName}'] Resolving inner GET variables...");
|
||||
ResolveGetVariableNodes(innerOps, innerConns);
|
||||
|
||||
OnLogMe?.Invoke($" [Function '{funcOp.FunctionName}'] Executing inner chain...");
|
||||
var innerStart = innerOps.FirstOrDefault(n => n.Title?.Equals("Begin", StringComparison.OrdinalIgnoreCase) == true);
|
||||
if (innerStart == null)
|
||||
{
|
||||
OnLogMe?.Invoke($" [Function '{funcOp.FunctionName}'] No Begin node found inside function!", logType.Error);
|
||||
return;
|
||||
}
|
||||
|
||||
var visited = new HashSet<string>();
|
||||
TraverseChain(innerStart, "end", innerConns, visited, true);
|
||||
|
||||
// Collect outputs from the inner End node
|
||||
var innerEnd = innerOps.FirstOrDefault(n => n.Title?.Equals("End", StringComparison.OrdinalIgnoreCase) == true);
|
||||
if (innerEnd != null)
|
||||
{
|
||||
for (int i = 0; i < funcOp.OutputParameters.Count; i++)
|
||||
{
|
||||
var endInputIndex = i + 1; // skip flow triangle
|
||||
if (endInputIndex < innerEnd.Input.Count)
|
||||
{
|
||||
var endConnector = innerEnd.Input[endInputIndex];
|
||||
var endCon = innerConns.FirstOrDefault(c => c.Input == endConnector);
|
||||
if (endCon != null)
|
||||
{
|
||||
var sourceId = endCon.Output.Operation.NodeId;
|
||||
if (outputs.TryGetValue(sourceId, out var resultVal))
|
||||
{
|
||||
var outerOutputIndex = i + 1; // skip flow triangle
|
||||
if (outerOutputIndex < funcOp.Output.Count)
|
||||
{
|
||||
funcOp.Output[outerOutputIndex].Value = double.TryParse(resultVal, out var dv) ? dv : 0;
|
||||
}
|
||||
outputs[funcOp.NodeId] = resultVal;
|
||||
OnLogMe?.Invoke($" [Function '{funcOp.FunctionName}'] Output '{funcOp.OutputParameters[i].Name}' = {resultVal}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
OnLogMe?.Invoke($"Function '{funcOp.FunctionName}' execution completed.");
|
||||
}
|
||||
|
||||
private string GetResponse(string url, string type)
|
||||
{
|
||||
string baseURL = !string.IsNullOrWhiteSpace(_authBaseUrl) ? _authBaseUrl : "https://localhost:7107";
|
||||
|
||||
119
Examples/Nodify.Calculator/FunctionOperationViewModel.cs
Normal file
119
Examples/Nodify.Calculator/FunctionOperationViewModel.cs
Normal file
@@ -0,0 +1,119 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Windows;
|
||||
|
||||
namespace Nodify.Calculator
|
||||
{
|
||||
public class FunctionOperationViewModel : CalculatorOperationViewModel
|
||||
{
|
||||
private string _functionName = "Function";
|
||||
public string FunctionName
|
||||
{
|
||||
get => _functionName;
|
||||
set
|
||||
{
|
||||
if (SetProperty(ref _functionName, value))
|
||||
{
|
||||
Title = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public List<FunctionParameterInfo> InputParameters { get; } = new List<FunctionParameterInfo>();
|
||||
public List<FunctionParameterInfo> OutputParameters { get; } = new List<FunctionParameterInfo>();
|
||||
|
||||
private OperationViewModel InnerBegin { get; }
|
||||
private OperationViewModel InnerEnd { get; }
|
||||
|
||||
public FunctionOperationViewModel()
|
||||
{
|
||||
// Add Begin and End nodes inside the inner calculator for flow-based editing
|
||||
InnerBegin = new SystemOperationViewModel
|
||||
{
|
||||
Title = "Begin",
|
||||
SystemOperationType = SystemOperations.BEGIN,
|
||||
Location = new Point(50, 150)
|
||||
};
|
||||
InnerBegin.Output.Add(new ConnectorViewModel { Title = "", Shape = ConnectorShape.Triangle, IsInput = false });
|
||||
|
||||
InnerEnd = new SystemOperationViewModel
|
||||
{
|
||||
Title = "End",
|
||||
SystemOperationType = SystemOperations.END,
|
||||
Location = new Point(600, 150)
|
||||
};
|
||||
InnerEnd.Input.Add(new ConnectorViewModel { Title = "", Shape = ConnectorShape.Triangle });
|
||||
|
||||
InnerCalculator.Operations.Add(InnerBegin);
|
||||
InnerCalculator.Operations.Add(InnerEnd);
|
||||
}
|
||||
|
||||
public void ConfigureParameters(List<FunctionParameterInfo> inputs, List<FunctionParameterInfo> outputs)
|
||||
{
|
||||
InputParameters.Clear();
|
||||
InputParameters.AddRange(inputs);
|
||||
OutputParameters.Clear();
|
||||
OutputParameters.AddRange(outputs);
|
||||
|
||||
// Add data output connectors to InnerBegin (these feed the inner flow with input values)
|
||||
foreach (var inp in inputs)
|
||||
{
|
||||
InnerBegin.Output.Add(new ConnectorViewModel
|
||||
{
|
||||
Title = $"{inp.Name} ({inp.Type})",
|
||||
Shape = ConnectorShape.Circle,
|
||||
IsInput = false
|
||||
});
|
||||
|
||||
// Also add an outer input connector on the function node
|
||||
Input.Add(new ConnectorViewModel
|
||||
{
|
||||
Title = $"{inp.Name} ({inp.Type})"
|
||||
});
|
||||
}
|
||||
|
||||
// Add data input connectors to InnerEnd (these collect inner flow results)
|
||||
foreach (var outp in outputs)
|
||||
{
|
||||
InnerEnd.Input.Add(new ConnectorViewModel
|
||||
{
|
||||
Title = $"{outp.Name} ({outp.Type})",
|
||||
Shape = ConnectorShape.Circle
|
||||
});
|
||||
|
||||
// Also add an outer output connector on the function node
|
||||
Output.Add(new ConnectorViewModel
|
||||
{
|
||||
Title = $"{outp.Name} ({outp.Type})",
|
||||
IsInput = false
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnInputValueChanged()
|
||||
{
|
||||
PropagateInputsToInner();
|
||||
}
|
||||
|
||||
public void PropagateInputsToInner()
|
||||
{
|
||||
// Propagate outer input values into the InnerBegin's data output connectors
|
||||
// The first output of InnerBegin is the flow triangle, data starts at index 1
|
||||
for (var i = 0; i < InputParameters.Count; i++)
|
||||
{
|
||||
var outerIndex = i; // outer Input: first is flow triangle (index 0), data starts at 1
|
||||
var innerIndex = i + 1; // InnerBegin Output: first is flow triangle, data starts at 1
|
||||
|
||||
if (outerIndex + 1 < Input.Count && innerIndex < InnerBegin.Output.Count)
|
||||
{
|
||||
InnerBegin.Output[innerIndex].Value = Input[outerIndex + 1].Value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class FunctionParameterInfo
|
||||
{
|
||||
public string Name { get; set; } = string.Empty;
|
||||
public string Type { get; set; } = "string";
|
||||
}
|
||||
}
|
||||
@@ -32,5 +32,8 @@ namespace Nodify.Calculator
|
||||
public string VariableType { get; set; } = string.Empty;
|
||||
public string DefaultValue { get; set; } = string.Empty;
|
||||
public bool IsSimpleVariable { get; set; }
|
||||
public bool IsFunction { get; set; }
|
||||
public List<FunctionParameterInfo> FunctionInputs { get; set; } = new List<FunctionParameterInfo>();
|
||||
public List<FunctionParameterInfo> FunctionOutputs { get; set; } = new List<FunctionParameterInfo>();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -275,6 +275,24 @@ namespace Nodify.Calculator
|
||||
//_o.Input.AddRange(input);
|
||||
return _o;
|
||||
case OperationType.System:
|
||||
if (info.sysOp == SystemOperations.FUNCTION)
|
||||
{
|
||||
var funcOp = new FunctionOperationViewModel
|
||||
{
|
||||
Title = info.Title,
|
||||
FunctionName = info.Title
|
||||
};
|
||||
// Add flow connectors (triangle)
|
||||
var funcFlowIn = new ConnectorViewModel { Title = "", Shape = ConnectorShape.Triangle };
|
||||
var funcFlowOut = new ConnectorViewModel { Title = "", Shape = ConnectorShape.Triangle, IsInput = false };
|
||||
funcOp.Input.Add(funcFlowIn);
|
||||
funcOp.Output.Add(funcFlowOut);
|
||||
|
||||
// Configure typed input/output parameters
|
||||
funcOp.ConfigureParameters(info.FunctionInputs, info.FunctionOutputs);
|
||||
return funcOp;
|
||||
}
|
||||
|
||||
if (info.sysOp == SystemOperations.AUTH)
|
||||
{
|
||||
var authOp = new AuthOperationViewModel
|
||||
|
||||
@@ -113,6 +113,7 @@ namespace Nodify.Calculator
|
||||
public NodifyObservableCollection<OperationInfoViewModel> SwaggerOperations { get; }
|
||||
public NodifyObservableCollection<OperationInfoViewModel> AvailableModels { get; }
|
||||
public NodifyObservableCollection<OperationInfoViewModel> AvailableVariables { get; }
|
||||
public NodifyObservableCollection<OperationInfoViewModel> AvailableFunctions { get; }
|
||||
public INodifyCommand CreateOperationCommand { get; }
|
||||
|
||||
[Newtonsoft.Json.JsonIgnore]
|
||||
@@ -125,6 +126,7 @@ namespace Nodify.Calculator
|
||||
List<OperationInfoViewModel> operations = new List<OperationInfoViewModel>();
|
||||
AvailableModels = new NodifyObservableCollection<OperationInfoViewModel>();
|
||||
AvailableVariables = new NodifyObservableCollection<OperationInfoViewModel>();
|
||||
AvailableFunctions = new NodifyObservableCollection<OperationInfoViewModel>();
|
||||
LoadVariablesFromDb();
|
||||
|
||||
var customModelDir = "CustomModels";
|
||||
@@ -158,6 +160,7 @@ namespace Nodify.Calculator
|
||||
CreateOperationCommand = new DelegateCommand<OperationInfoViewModel>(CreateOperation);
|
||||
ImportSwaggerCommand = new DelegateCommand(ImportSwagger);
|
||||
AddVariableCommand = new DelegateCommand(AddVariable);
|
||||
CreateFunctionCommand = new DelegateCommand(CreateFunction);
|
||||
}
|
||||
|
||||
|
||||
@@ -180,6 +183,37 @@ namespace Nodify.Calculator
|
||||
|
||||
public INodifyCommand ImportSwaggerCommand { get; }
|
||||
public INodifyCommand AddVariableCommand { get; }
|
||||
public INodifyCommand CreateFunctionCommand { get; }
|
||||
|
||||
private void CreateFunction()
|
||||
{
|
||||
var dialog = new CreateFunctionDialog();
|
||||
dialog.Owner = System.Windows.Application.Current.MainWindow;
|
||||
if (dialog.ShowDialog() != true)
|
||||
return;
|
||||
|
||||
var funcName = dialog.FunctionName;
|
||||
|
||||
if (AvailableFunctions.Any(f => f.Title == funcName))
|
||||
{
|
||||
MessageBox.Show($"A function named '{funcName}' already exists.", "Duplicate Function", MessageBoxButton.OK, MessageBoxImage.Warning);
|
||||
return;
|
||||
}
|
||||
|
||||
var funcInfo = new OperationInfoViewModel
|
||||
{
|
||||
Title = funcName,
|
||||
Type = OperationType.System,
|
||||
sysOp = SystemOperations.FUNCTION,
|
||||
IsFlowNode = true,
|
||||
IsFunction = true,
|
||||
FunctionInputs = new System.Collections.Generic.List<FunctionParameterInfo>(dialog.InputParameters),
|
||||
FunctionOutputs = new System.Collections.Generic.List<FunctionParameterInfo>(dialog.OutputParameters)
|
||||
};
|
||||
|
||||
AvailableFunctions.Add(funcInfo);
|
||||
AvailableOperations.Add(funcInfo);
|
||||
}
|
||||
|
||||
private void AddVariable()
|
||||
{
|
||||
|
||||
@@ -17,7 +17,8 @@ namespace Nodify.Calculator
|
||||
GET_SET,
|
||||
PARSEJSON,
|
||||
SPLIT,
|
||||
AUTH
|
||||
AUTH,
|
||||
FUNCTION
|
||||
}
|
||||
|
||||
public class SystemOperationViewModel : OperationViewModel
|
||||
|
||||
Reference in New Issue
Block a user