diff --git a/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/ActivityProperties/Models.cs b/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/ActivityProperties/Models.cs
index 957477079..b34b385a0 100644
--- a/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/ActivityProperties/Models.cs
+++ b/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/ActivityProperties/Models.cs
@@ -1,5 +1,6 @@
+using Elsa.Api.Client.Resources.ActivityDescriptors.Models;
using Microsoft.AspNetCore.Components;
namespace Elsa.Studio.Workflows.Components.WorkflowDefinitionEditor.Components.ActivityProperties;
-public record ActivityInputDisplayModel(RenderFragment Editor);
\ No newline at end of file
+public record ActivityInputDisplayModel(RenderFragment Editor, InputDescriptor InputDescriptor);
\ No newline at end of file
diff --git a/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/ActivityProperties/Tabs/InputsTab.razor b/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/ActivityProperties/Tabs/InputsTab.razor
index 8112b9c03..5ed49f39e 100644
--- a/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/ActivityProperties/Tabs/InputsTab.razor
+++ b/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/ActivityProperties/Tabs/InputsTab.razor
@@ -4,7 +4,10 @@
@foreach (var inputModel in InputDisplayModels)
{
- @inputModel.Editor
+ if (IsVisibleInput(inputModel))
+ {
+ @inputModel.Editor
+ }
}
\ No newline at end of file
diff --git a/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/ActivityProperties/Tabs/InputsTab.razor.cs b/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/ActivityProperties/Tabs/InputsTab.razor.cs
index f12209962..96101a508 100644
--- a/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/ActivityProperties/Tabs/InputsTab.razor.cs
+++ b/src/modules/Elsa.Studio.Workflows/Components/WorkflowDefinitionEditor/Components/ActivityProperties/Tabs/InputsTab.razor.cs
@@ -64,6 +64,10 @@ public InputsTab()
private ICollection OutputDescriptors { get; set; } = new List();
private ICollection InputDisplayModels { get; set; } = new List();
+ private List _selectedStates = [];
+ private static Dictionary _InputDescriptors = new();
+ private static Dictionary _previousStates = new();
+
///
protected override async Task OnParametersSetAsync()
{
@@ -73,20 +77,63 @@ protected override async Task OnParametersSetAsync()
InputDescriptors = ActivityDescriptor.Inputs.ToList();
OutputDescriptors = ActivityDescriptor.Outputs.ToList();
InputDisplayModels = (await BuildInputEditorModels(Activity, ActivityDescriptor, InputDescriptors)).ToList();
+ StateHasChanged();
}
private async Task> BuildInputEditorModels(JsonObject activity, ActivityDescriptor activityDescriptor, ICollection inputDescriptors)
{
var models = new List();
- var browsableInputDescriptors = inputDescriptors.Where(x => x.IsBrowsable == true).ToList();
- foreach (var inputDescriptor in browsableInputDescriptors)
+ foreach (var inputDescriptor in inputDescriptors)
{
var inputName = inputDescriptor.Name.Camelize();
var value = activity.GetProperty(inputName);
var wrappedInput = inputDescriptor.IsWrapped ? ToWrappedInput(value) : default;
var syntaxProvider = wrappedInput != null ? ExpressionDescriptorProvider.GetByType(wrappedInput.Expression.Type) : default;
+ // Check if we have a custom input
+ JsonDocument? InputDescriptor = null;
+ if (inputDescriptor.Description is not null)
+ {
+ SetInputDescriptor(inputDescriptor);
+ InputDescriptor = GetInputDescriptor(inputDescriptor);
+
+ if (InputDescriptor is not null)
+ {
+ string? inputType = InputDescriptor.RootElement.GetProperty("InputType").GetString();
+ // Check if we have conditional inputs
+ if (inputType == "StateDropdown")
+ {
+ if (wrappedInput is not null)
+ {
+ // Add the current value to the selected states
+ AddSelectedState(inputDescriptor, wrappedInput);
+ UpdateDescription(inputDescriptor, wrappedInput);
+ }
+ else if (wrappedInput is null && inputDescriptor.DefaultValue is not null)
+ {
+ // Add the default value to the selected states
+ AddSelectedState(inputDescriptor, inputDescriptor.DefaultValue);
+ UpdateDescription(inputDescriptor, inputDescriptor.DefaultValue);
+ }
+ else if (wrappedInput is null || (wrappedInput is not null && string.IsNullOrEmpty(wrappedInput.Expression.ToString())))
+ {
+ // Empty state && InputDescriptor exists, therefore we hide the description
+ inputDescriptor.Description = "";
+ }
+
+ }
+ else if (inputType == "ConditionalInput")
+ {
+ inputDescriptor.Description = InputDescriptor.RootElement.GetProperty("Description").EnumerateArray().First().GetString();
+ }
+ else
+ {
+ inputDescriptor.Description = InputDescriptor.RootElement.GetProperty("Description").GetString();
+ }
+ }
+ }
+
// Check if refresh is needed.
if (inputDescriptor.UISpecifications != null
&& inputDescriptor.UISpecifications.TryGetValue("Refresh", out var refreshInput)
@@ -109,17 +156,179 @@ private async Task> BuildInputEditorModel
Value = input,
SelectedExpressionDescriptor = syntaxProvider,
UIHintHandler = uiHintHandler,
- IsReadOnly = (Workspace?.IsReadOnly ?? false) || (inputDescriptor.IsReadOnly ?? false),
+ IsReadOnly = Workspace?.IsReadOnly ?? false
};
- context.OnValueChanged = async v => await HandleValueChangedAsync(context, v);
+ context.OnValueChanged = HandleValueChangedAsync(context, inputDescriptor);
var editor = uiHintHandler.DisplayInputEditor(context);
- models.Add(new ActivityInputDisplayModel(editor));
+ models.Add(new ActivityInputDisplayModel(editor, inputDescriptor));
}
return models;
}
+ private string GetInputDescriptorKey(InputDescriptor inputDescriptor)
+ {
+ return ActivityDescriptor?.Name + inputDescriptor.Name;
+ }
+
+ private JsonDocument? GetInputDescriptor(InputDescriptor inputDescriptor)
+ {
+ return _InputDescriptors.GetValueOrDefault(GetInputDescriptorKey(inputDescriptor));
+ }
+
+ private void SetInputDescriptor(InputDescriptor inputDescriptor)
+ {
+ try
+ {
+ var InputDescriptor = JsonDocument.Parse(inputDescriptor.Description!);
+ _InputDescriptors[GetInputDescriptorKey(inputDescriptor)] = InputDescriptor;
+ }
+ catch
+ {
+ // Ignore --> Standard Elsa 3 descriptor
+ }
+ }
+
+ private void AddSelectedState(InputDescriptor inputDescriptor, WrappedInput? v)
+ {
+ var InputDescriptor = GetInputDescriptor(inputDescriptor);
+ if (v is null || InputDescriptor is null) return;
+
+ var valueAsString = v!.Expression.ToString();
+ AddSelectedState(inputDescriptor, valueAsString);
+ UpdateDescription(inputDescriptor, v);
+ }
+
+ private void AddSelectedState(InputDescriptor inputDescriptor, object? value)
+ {
+ if (value is null) return;
+
+ var InputDescriptor = GetInputDescriptor(inputDescriptor);
+ if (InputDescriptor is null) return;
+
+ var inputDescriptorKey = GetInputDescriptorKey(inputDescriptor);
+ // Remove the previous state
+ var previousState = _previousStates.GetValueOrDefault(inputDescriptorKey, string.Empty);
+ if (!string.IsNullOrEmpty(previousState))
+ {
+ RemoveSelectedState(previousState);
+ }
+
+ var valueAsString = value as string;
+ if (value is JsonElement)
+ {
+ valueAsString = ((JsonElement)value).GetString();
+ }
+
+ var stateNames = InputDescriptor.RootElement.GetProperty("Options").EnumerateArray();
+ var stateIds = InputDescriptor.RootElement.GetProperty("Ids").EnumerateArray();
+
+ for (var i = 0; i < stateNames.Count(); ++i)
+ {
+ var current = stateNames.ElementAt(i);
+ if (current.GetString() == valueAsString)
+ {
+ var id = stateIds.ElementAt(i).GetString()!;
+
+ // Ensure that we have no duplicates
+ RemoveSelectedState(id);
+
+ _selectedStates.Add(id);
+ _previousStates[inputDescriptorKey] = id;
+ break;
+ }
+ }
+
+ StateHasChanged();
+ }
+
+ private void RemoveSelectedState(string name)
+ {
+ _selectedStates.Remove(name);
+ }
+
+ private Func