Fix metadata and serialization
This commit is contained in:
parent
c74b105e19
commit
c13825a930
|
|
@ -51,7 +51,7 @@ public static partial class Workflows
|
|||
|
||||
draft.Root = root;
|
||||
|
||||
draft.Metadata = draft.Metadata with
|
||||
draft.WorkflowMetadata = draft.WorkflowMetadata with
|
||||
{
|
||||
Name = model.Name,
|
||||
Description = model.Description
|
||||
|
|
|
|||
|
|
@ -28,5 +28,6 @@ public class ActivityAttribute : Attribute
|
|||
public string? Namespace { get; }
|
||||
public string? TypeName { get; }
|
||||
public string? Description { get; }
|
||||
public string? DisplayName { get; }
|
||||
public string? Category { get; }
|
||||
}
|
||||
|
|
@ -11,6 +11,7 @@ public class WorkflowDefinitionBuilder : IWorkflowDefinitionBuilder
|
|||
public int Version { get; private set; } = 1;
|
||||
public IActivity? Root { get; private set; }
|
||||
public ICollection<Variable> Variables { get; set; } = new List<Variable>();
|
||||
public IDictionary<string, object> Metadata { get; set; } = new Dictionary<string, object>();
|
||||
public IDictionary<string, object> ApplicationProperties { get; set; } = new Dictionary<string, object>();
|
||||
|
||||
public IWorkflowDefinitionBuilder WithId(string id)
|
||||
|
|
@ -43,6 +44,12 @@ public class WorkflowDefinitionBuilder : IWorkflowDefinitionBuilder
|
|||
return this;
|
||||
}
|
||||
|
||||
public IWorkflowDefinitionBuilder WithMetadata(string name, object value)
|
||||
{
|
||||
Metadata[name] = value;
|
||||
return this;
|
||||
}
|
||||
|
||||
public IWorkflowDefinitionBuilder WithApplicationProperty(string name, object value)
|
||||
{
|
||||
ApplicationProperties[name] = value;
|
||||
|
|
@ -57,6 +64,6 @@ public class WorkflowDefinitionBuilder : IWorkflowDefinitionBuilder
|
|||
var identity = new WorkflowIdentity(definitionId, Version, id);
|
||||
var publication = WorkflowPublication.LatestAndPublished;
|
||||
var metadata = new WorkflowMetadata();
|
||||
return new Workflow(identity, publication, metadata, root, Variables, ApplicationProperties);
|
||||
return new Workflow(identity, publication, metadata, root, Variables, Metadata, ApplicationProperties);
|
||||
}
|
||||
}
|
||||
|
|
@ -12,6 +12,7 @@ public abstract class Activity : IActivity
|
|||
public string TypeName { get; set; }
|
||||
public bool CanStartWorkflow { get; set; }
|
||||
public IDictionary<string, object> ApplicationProperties { get; set; } = new Dictionary<string, object>();
|
||||
public IDictionary<string, object> Metadata { get; set; } = new Dictionary<string, object>();
|
||||
|
||||
protected virtual ValueTask ExecuteAsync(ActivityExecutionContext context)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -8,20 +8,29 @@ public class Workflow : Composite, ICloneable
|
|||
public Workflow(
|
||||
WorkflowIdentity identity,
|
||||
WorkflowPublication publication,
|
||||
WorkflowMetadata metadata,
|
||||
WorkflowMetadata workflowMetadata,
|
||||
IActivity root,
|
||||
ICollection<Variable> variables,
|
||||
IDictionary<string, object> metadata,
|
||||
IDictionary<string, object> applicationProperties)
|
||||
{
|
||||
Identity = identity;
|
||||
Publication = publication;
|
||||
Metadata = metadata;
|
||||
WorkflowMetadata = workflowMetadata;
|
||||
Variables = variables;
|
||||
Metadata = metadata;
|
||||
ApplicationProperties = applicationProperties;
|
||||
Root = root;
|
||||
}
|
||||
|
||||
public static Workflow FromActivity(IActivity root) => new(WorkflowIdentity.VersionOne, WorkflowPublication.LatestDraft, new WorkflowMetadata(), root, new List<Variable>(), new Dictionary<string, object>());
|
||||
public static Workflow FromActivity(IActivity root) => new(
|
||||
WorkflowIdentity.VersionOne,
|
||||
WorkflowPublication.LatestDraft,
|
||||
new WorkflowMetadata(),
|
||||
root,
|
||||
new List<Variable>(),
|
||||
new Dictionary<string, object>(),
|
||||
new Dictionary<string, object>());
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new memory register initialized with this workflow's variables.
|
||||
|
|
@ -35,7 +44,7 @@ public class Workflow : Composite, ICloneable
|
|||
|
||||
public WorkflowIdentity Identity { get; set; }
|
||||
public WorkflowPublication Publication { get; set; }
|
||||
public WorkflowMetadata Metadata { get; set; }
|
||||
public WorkflowMetadata WorkflowMetadata { get; set; }
|
||||
public ICollection<Variable> Variables { get; init; }
|
||||
public Workflow Clone() => (Workflow)((ICloneable)this).Clone();
|
||||
object ICloneable.Clone() => MemberwiseClone();
|
||||
|
|
|
|||
|
|
@ -27,15 +27,16 @@ public class ActivityDescriber : IActivityDescriber
|
|||
|
||||
public ValueTask<ActivityDescriptor> DescribeActivityAsync(Type activityType, CancellationToken cancellationToken = default)
|
||||
{
|
||||
var ns = TypeNameHelper.GenerateNamespace(activityType);
|
||||
var typeName = activityType.Name;
|
||||
var fullTypeName = TypeNameHelper.GenerateTypeName(activityType, ns);
|
||||
var activityAttr = activityType.GetCustomAttribute<ActivityAttribute>();
|
||||
var ns = activityAttr?.Namespace ?? TypeNameHelper.GenerateNamespace(activityType);
|
||||
var typeName = activityAttr?.TypeName ?? activityType.Name;
|
||||
var fullTypeName = $"{ns}.{typeName}";
|
||||
var displayNameAttr = activityType.GetCustomAttribute<DisplayNameAttribute>();
|
||||
var displayName = displayNameAttr?.DisplayName ?? typeName.Humanize(LetterCasing.Title);
|
||||
var displayName = displayNameAttr?.DisplayName ?? activityAttr?.DisplayName ?? typeName.Humanize(LetterCasing.Title);
|
||||
var categoryAttr = activityType.GetCustomAttribute<CategoryAttribute>();
|
||||
var category = categoryAttr?.Category ?? TypeNameHelper.GetCategoryFromNamespace(ns) ?? "Miscellaneous";
|
||||
var category = categoryAttr?.Category ?? activityAttr?.Category ?? TypeNameHelper.GetCategoryFromNamespace(ns) ?? "Miscellaneous";
|
||||
var descriptionAttr = activityType.GetCustomAttribute<DescriptionAttribute>();
|
||||
var description = descriptionAttr?.Description;
|
||||
var description = descriptionAttr?.Description ?? activityAttr?.Description;
|
||||
|
||||
var outboundPorts =
|
||||
from prop in activityType.GetProperties(BindingFlags.Public | BindingFlags.Instance)
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@ namespace Elsa.Management.Services
|
|||
new WorkflowMetadata(CreatedAt: _systemClock.UtcNow),
|
||||
new Sequence(),
|
||||
new List<Variable>(),
|
||||
new Dictionary<string, object>(),
|
||||
new Dictionary<string, object>());
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -69,6 +69,7 @@ export class FlowchartComponent implements ContainerActivityComponent {
|
|||
const activity: Activity = {
|
||||
id: uuid(),
|
||||
typeName: descriptor.activityType,
|
||||
applicationProperties: {},
|
||||
metadata: {
|
||||
designer: {
|
||||
position: {
|
||||
|
|
@ -181,6 +182,7 @@ export class FlowchartComponent implements ContainerActivityComponent {
|
|||
id: this.rootId,
|
||||
start: first(activities)?.id,
|
||||
metadata: {},
|
||||
applicationProperties: {},
|
||||
variables: []
|
||||
} as Flowchart;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -185,7 +185,6 @@ export class WorkflowEditor {
|
|||
private getWorkflowInternal = async (): Promise<Workflow> => {
|
||||
const root = await this.canvas.exportGraph();
|
||||
const workflow = this.workflow;
|
||||
|
||||
workflow.root = root;
|
||||
return workflow;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ export interface Activity {
|
|||
id: string;
|
||||
typeName: string;
|
||||
metadata: any;
|
||||
applicationProperties: any;
|
||||
|
||||
[name: string]: any;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ public record Connection(IActivity Source, IActivity Target, string? SourcePort,
|
|||
[Activity("Elsa", "Workflows", "A flowchart is a collection of activities and connections between them.")]
|
||||
public class Flowchart : Container
|
||||
{
|
||||
[Node] public IActivity? Start { get; set; } = default!;
|
||||
[Node] public IActivity? Start { get; set; }
|
||||
public ICollection<Connection> Connections { get; set; } = new List<Connection>();
|
||||
|
||||
protected override void ScheduleChildren(ActivityExecutionContext context)
|
||||
|
|
|
|||
|
|
@ -20,12 +20,12 @@ public class FlowchartJsonConverter : JsonConverter<Flowchart>
|
|||
throw new JsonException("Failed to parse JsonDocument");
|
||||
|
||||
var connectionsElement = doc.RootElement.GetProperty("connections");
|
||||
var applicationPropertiesElement = doc.RootElement.GetProperty("applicationProperties");
|
||||
var metadataElement = doc.RootElement.GetProperty("metadata");
|
||||
var activitiesElement = doc.RootElement.GetProperty("activities");
|
||||
var id = doc.RootElement.GetProperty("id").GetString()!;
|
||||
var startId = doc.RootElement.TryGetProperty("start", out var startElement) ? startElement.GetString() : default;
|
||||
var rootActivities = activitiesElement.Deserialize<ICollection<IActivity>>(options) ?? new List<IActivity>();
|
||||
var applicationProperties = applicationPropertiesElement.Deserialize<IDictionary<string, object>>(options) ?? new Dictionary<string, object>();
|
||||
var metadata = metadataElement.Deserialize<IDictionary<string, object>>(options) ?? new Dictionary<string, object>();
|
||||
var start = rootActivities.FirstOrDefault(x => x.Id == startId) ?? rootActivities.FirstOrDefault();
|
||||
var connectionSerializerOptions = new JsonSerializerOptions(options);
|
||||
var activities = WalkActivityTree(rootActivities).ToList();
|
||||
|
|
@ -37,7 +37,7 @@ public class FlowchartJsonConverter : JsonConverter<Flowchart>
|
|||
return new Flowchart
|
||||
{
|
||||
Id = id,
|
||||
ApplicationProperties = applicationProperties,
|
||||
Metadata = metadata,
|
||||
Activities = rootActivities,
|
||||
Connections = connections,
|
||||
Start = start,
|
||||
|
|
@ -55,6 +55,7 @@ public class FlowchartJsonConverter : JsonConverter<Flowchart>
|
|||
{
|
||||
value.TypeName,
|
||||
value.Id,
|
||||
value.Metadata,
|
||||
value.ApplicationProperties,
|
||||
Start = value.Start?.Id,
|
||||
value.Activities,
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ public class WorkflowDefinition : Entity
|
|||
public int Version { get; set; } = 1;
|
||||
public IActivity Root { get; set; } = default!;
|
||||
public ICollection<Variable> Variables { get; set; } = new List<Variable>();
|
||||
public IDictionary<string, object> Metadata { get; set; } = new Dictionary<string, object>();
|
||||
public IDictionary<string, object> ApplicationProperties { get; set; } = new Dictionary<string, object>();
|
||||
public bool IsLatest { get; set; }
|
||||
public bool IsPublished { get; set; }
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ public class WorkflowDefinitionMapper
|
|||
new WorkflowMetadata(definition.Name, definition.Description, definition.CreatedAt),
|
||||
definition.Root,
|
||||
definition.Variables,
|
||||
definition.Metadata,
|
||||
definition.ApplicationProperties);
|
||||
}
|
||||
|
||||
|
|
@ -25,7 +26,7 @@ public class WorkflowDefinitionMapper
|
|||
{
|
||||
var identity = workflow.Identity;
|
||||
var publication = workflow.Publication;
|
||||
var metadata = workflow.Metadata;
|
||||
var metadata = workflow.WorkflowMetadata;
|
||||
|
||||
definition.Id = identity.Id;
|
||||
definition.DefinitionId = identity.DefinitionId;
|
||||
|
|
@ -37,6 +38,7 @@ public class WorkflowDefinitionMapper
|
|||
definition.IsLatest = publication.IsLatest;
|
||||
definition.IsPublished = publication.IsPublished;
|
||||
definition.Variables = workflow.Variables;
|
||||
definition.Metadata = workflow.Metadata;
|
||||
definition.ApplicationProperties = workflow.ApplicationProperties;
|
||||
|
||||
return definition;
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ namespace Elsa.Persistence.EntityFrameworkCore.Configuration
|
|||
{
|
||||
builder.Ignore(x => x.Root);
|
||||
builder.Ignore(x => x.Variables);
|
||||
builder.Ignore(x => x.Metadata);
|
||||
builder.Ignore(x => x.ApplicationProperties);
|
||||
builder.Property<string>("Data");
|
||||
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ public class WorkflowDefinitionSerializer : IEntitySerializer<WorkflowDefinition
|
|||
{
|
||||
entity.Root,
|
||||
entity.Variables,
|
||||
entity.Metadata,
|
||||
entity.ApplicationProperties
|
||||
};
|
||||
|
||||
|
|
@ -33,7 +34,7 @@ public class WorkflowDefinitionSerializer : IEntitySerializer<WorkflowDefinition
|
|||
|
||||
public void Deserialize(ElsaDbContext dbContext, WorkflowDefinition entity)
|
||||
{
|
||||
var data = new WorkflowDefinitionState(entity.Root, entity.Variables, entity.ApplicationProperties);
|
||||
var data = new WorkflowDefinitionState(entity.Root, entity.Variables, entity.Metadata, entity.ApplicationProperties);
|
||||
var json = (string?) dbContext.Entry(entity).Property("Data").CurrentValue;
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(json))
|
||||
|
|
@ -44,6 +45,7 @@ public class WorkflowDefinitionSerializer : IEntitySerializer<WorkflowDefinition
|
|||
|
||||
entity.Root = data.Root;
|
||||
entity.Variables = data.Variables;
|
||||
entity.Metadata = data.Metadata;
|
||||
entity.ApplicationProperties = data.ApplicationProperties;
|
||||
}
|
||||
|
||||
|
|
@ -54,15 +56,17 @@ public class WorkflowDefinitionSerializer : IEntitySerializer<WorkflowDefinition
|
|||
{
|
||||
}
|
||||
|
||||
public WorkflowDefinitionState(IActivity root, ICollection<Variable> variables, IDictionary<string, object> applicationProperties)
|
||||
public WorkflowDefinitionState(IActivity root, ICollection<Variable> variables, IDictionary<string, object> metadata, IDictionary<string, object> applicationProperties)
|
||||
{
|
||||
Root = root;
|
||||
Variables = variables;
|
||||
Metadata = metadata;
|
||||
ApplicationProperties = applicationProperties;
|
||||
}
|
||||
|
||||
public IActivity Root { get; init; } = default!;
|
||||
public ICollection<Variable> Variables { get; set; } = new List<Variable>();
|
||||
public IDictionary<string, object> Metadata { get; set; } = new Dictionary<string, object>();
|
||||
public IDictionary<string, object> ApplicationProperties { get; set; } = new Dictionary<string, object>();
|
||||
}
|
||||
}
|
||||
|
|
@ -33,7 +33,7 @@ public class ConfigurationWorkflowProvider : IWorkflowProvider
|
|||
|
||||
public ValueTask<Workflow?> FindByNameAsync(string name, VersionOptions versionOptions, CancellationToken cancellationToken = default)
|
||||
{
|
||||
var result = _workflows.FirstOrDefault(x => x.Metadata.Name == name && x.WithVersion(versionOptions));
|
||||
var result = _workflows.FirstOrDefault(x => x.WorkflowMetadata.Name == name && x.WithVersion(versionOptions));
|
||||
return ValueTask.FromResult(result);
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue