| | | 1 | | using Elsa.Extensions; |
| | | 2 | | using Elsa.Workflows.Management.Entities; |
| | | 3 | | using Elsa.Workflows.Models; |
| | | 4 | | using Humanizer; |
| | | 5 | | |
| | | 6 | | namespace Elsa.Workflows.Management.Activities.WorkflowDefinitionActivity; |
| | | 7 | | |
| | | 8 | | public class WorkflowDefinitionActivityDescriptorFactory |
| | | 9 | | { |
| | | 10 | | public ActivityDescriptor CreateDescriptor(WorkflowDefinition definition, WorkflowDefinition? latestPublishedDefinit |
| | | 11 | | { |
| | 883 | 12 | | var typeName = definition.Name!.Pascalize(); |
| | 883 | 13 | | var tenantId = definition.TenantId; |
| | | 14 | | |
| | 883 | 15 | | var ports = definition.Outcomes.Select(outcome => new Port |
| | 883 | 16 | | { |
| | 883 | 17 | | Name = outcome, |
| | 883 | 18 | | DisplayName = outcome, |
| | 883 | 19 | | IsBrowsable = true, |
| | 883 | 20 | | Type = PortType.Flow |
| | 883 | 21 | | }).ToList(); |
| | | 22 | | |
| | 883 | 23 | | var rootPort = new Port |
| | 883 | 24 | | { |
| | 883 | 25 | | Name = nameof(WorkflowDefinitionActivity.Root), |
| | 883 | 26 | | DisplayName = "Root", |
| | 883 | 27 | | IsBrowsable = false, |
| | 883 | 28 | | Type = PortType.Embedded |
| | 883 | 29 | | }; |
| | | 30 | | |
| | 883 | 31 | | ports.Insert(0, rootPort); |
| | | 32 | | |
| | 883 | 33 | | return new() |
| | 883 | 34 | | { |
| | 883 | 35 | | TenantId = tenantId, |
| | 883 | 36 | | TypeName = typeName, |
| | 883 | 37 | | ClrType = typeof(WorkflowDefinitionActivity), |
| | 883 | 38 | | Name = typeName, |
| | 883 | 39 | | Version = definition.Version, |
| | 883 | 40 | | DisplayName = definition.Name, |
| | 883 | 41 | | Description = definition.Description, |
| | 883 | 42 | | Category = definition.Options.ActivityCategory ?? "Workflows", |
| | 883 | 43 | | Kind = ActivityKind.Action, |
| | 883 | 44 | | IsBrowsable = definition.IsPublished, |
| | 883 | 45 | | Inputs = DescribeInputs(definition).ToList(), |
| | 883 | 46 | | Outputs = DescribeOutputs(definition).ToList(), |
| | 883 | 47 | | Ports = ports, |
| | 883 | 48 | | CustomProperties = |
| | 883 | 49 | | { |
| | 883 | 50 | | ["RootType"] = nameof(WorkflowDefinitionActivity), |
| | 883 | 51 | | ["WorkflowDefinitionId"] = definition.DefinitionId, |
| | 883 | 52 | | ["WorkflowDefinitionVersionId"] = definition.Id |
| | 883 | 53 | | }, |
| | 883 | 54 | | ConstructionProperties = new Dictionary<string, object> |
| | 883 | 55 | | { |
| | 883 | 56 | | [nameof(WorkflowDefinitionActivity.WorkflowDefinitionId)] = definition.DefinitionId, |
| | 883 | 57 | | [nameof(WorkflowDefinitionActivity.WorkflowDefinitionVersionId)] = definition.Id, |
| | 883 | 58 | | [nameof(WorkflowDefinitionActivity.Version)] = definition.Version, |
| | 883 | 59 | | }, |
| | 883 | 60 | | Constructor = context => |
| | 883 | 61 | | { |
| | 432 | 62 | | var activityResult = context.CreateActivity<WorkflowDefinitionActivity>(); |
| | 432 | 63 | | var activity = activityResult.Activity; |
| | 432 | 64 | | activity.Type = typeName; |
| | 432 | 65 | | activity.WorkflowDefinitionId = definition.DefinitionId; |
| | 432 | 66 | | activity.WorkflowDefinitionVersionId = definition.Id; |
| | 432 | 67 | | activity.Version = definition.Version; |
| | 432 | 68 | | activity.LatestAvailablePublishedVersion = latestPublishedDefinition?.Version ?? definition.Version; |
| | 432 | 69 | | activity.LatestAvailablePublishedVersionId = latestPublishedDefinition?.Id ?? definition.Id; |
| | 883 | 70 | | |
| | 432 | 71 | | return activityResult; |
| | 883 | 72 | | } |
| | 883 | 73 | | }; |
| | | 74 | | } |
| | | 75 | | |
| | | 76 | | private static IEnumerable<InputDescriptor> DescribeInputs(WorkflowDefinition definition) |
| | | 77 | | { |
| | 883 | 78 | | var inputs = definition.Inputs.Select(inputDefinition => |
| | 883 | 79 | | { |
| | 77 | 80 | | var nakedType = inputDefinition.Type; |
| | 77 | 81 | | var inputName = inputDefinition.Name; |
| | 77 | 82 | | var safeInputName = PropertyNameHelper.GetSafePropertyName(typeof(WorkflowDefinitionActivity), inputName); |
| | 883 | 83 | | |
| | 77 | 84 | | return new InputDescriptor |
| | 77 | 85 | | { |
| | 77 | 86 | | Type = nakedType, |
| | 77 | 87 | | IsWrapped = true, |
| | 34 | 88 | | ValueGetter = activity => activity.SyntheticProperties.GetValueOrDefault(safeInputName), |
| | 0 | 89 | | ValueSetter = (activity, value) => activity.SyntheticProperties[safeInputName] = value!, |
| | 77 | 90 | | Name = safeInputName, |
| | 77 | 91 | | DisplayName = inputDefinition.DisplayName, |
| | 77 | 92 | | Description = inputDefinition.Description, |
| | 77 | 93 | | Category = inputDefinition.Category, |
| | 77 | 94 | | UIHint = inputDefinition.UIHint, |
| | 77 | 95 | | StorageDriverType = inputDefinition.StorageDriverType, |
| | 77 | 96 | | IsSynthetic = true |
| | 77 | 97 | | }; |
| | 883 | 98 | | }); |
| | | 99 | | |
| | 1920 | 100 | | foreach (var input in inputs) |
| | 77 | 101 | | yield return input; |
| | 883 | 102 | | } |
| | | 103 | | |
| | | 104 | | private static IEnumerable<OutputDescriptor> DescribeOutputs(WorkflowDefinition definition) |
| | | 105 | | { |
| | 883 | 106 | | return definition.Outputs.Select(outputDefinition => |
| | 883 | 107 | | { |
| | 231 | 108 | | var nakedType = outputDefinition.Type; |
| | 231 | 109 | | var outputName = outputDefinition.Name; |
| | 231 | 110 | | var safeOutputName = PropertyNameHelper.GetSafePropertyName(typeof(WorkflowDefinitionActivity), outputName); |
| | 883 | 111 | | |
| | 231 | 112 | | return new OutputDescriptor |
| | 231 | 113 | | { |
| | 231 | 114 | | Type = nakedType, |
| | 9 | 115 | | ValueGetter = activity => activity.SyntheticProperties.GetValueOrDefault(safeOutputName), |
| | 0 | 116 | | ValueSetter = (activity, value) => activity.SyntheticProperties[safeOutputName] = value!, |
| | 231 | 117 | | Name = safeOutputName, |
| | 231 | 118 | | DisplayName = outputDefinition.DisplayName, |
| | 231 | 119 | | Description = outputDefinition.Description, |
| | 231 | 120 | | IsSynthetic = true |
| | 231 | 121 | | }; |
| | 883 | 122 | | }); |
| | | 123 | | } |
| | | 124 | | } |