Add support for overriding display name and description

This commit is contained in:
Sipke Schoorstra 2020-12-26 21:55:02 +01:00
parent 42bcade5fc
commit d04cd93536
24 changed files with 102 additions and 50 deletions

View file

@ -7,10 +7,12 @@ namespace Elsa.Client.Models
{
[DataMember(Order = 1)] public string Id { get; set; } = default!;
[DataMember(Order = 2)] public string? Name { get; set; }
[DataMember(Order = 3)] public string Type { get; set; } = default!;
[DataMember(Order = 4)] public bool PersistWorkflow { get; set; }
[DataMember(Order = 5)] public bool LoadWorkflowContext { get; set; }
[DataMember(Order = 6)] public bool SaveWorkflowContext { get; set; }
[DataMember(Order = 7)] public Variables Properties { get; set; } = new();
[DataMember(Order = 3)] public string? DisplayName { get; set; }
[DataMember(Order = 4)] public string? Description { get; set;}
[DataMember(Order = 5)] public string Type { get; set; } = default!;
[DataMember(Order = 6)] public bool PersistWorkflow { get; set; }
[DataMember(Order = 7)] public bool LoadWorkflowContext { get; set; }
[DataMember(Order = 8)] public bool SaveWorkflowContext { get; set; }
[DataMember(Order = 9)] public Variables Properties { get; set; } = new();
}
}

View file

@ -9,31 +9,30 @@ namespace Elsa.Client.Models
[DataMember(Order = 2)] public string? TenantId { get; set;}
[DataMember(Order = 3)] public bool IsSingleton { get; set;}
[DataMember(Order = 4)] public bool IsEnabled { get; set;}
[DataMember(Order = 5)] public string? Description { get; set;}
[DataMember(Order = 6)] public bool IsPublished { get; set;}
[DataMember(Order = 7)] public bool IsLatest { get; set;}
[DataMember(Order = 5)] public bool IsPublished { get; set;}
[DataMember(Order = 6)] public bool IsLatest { get; set;}
/// <summary>
/// An initial set of variables available to workflow instances.
/// </summary>
[DataMember(Order = 8)]
[DataMember(Order = 7)]
public Variables Variables { get; set;} = new();
/// <summary>
/// An optional context type around which this workflow revolves. For example, a document, a leave request or a job application.
/// </summary>
[DataMember(Order = 9)]
[DataMember(Order = 8)]
public WorkflowContextOptions? ContextOptions { get; set; }
[DataMember(Order = 10)] public WorkflowPersistenceBehavior PersistenceBehavior { get; set;}
[DataMember(Order = 11)] public bool DeleteCompletedInstances { get; set;}
[DataMember(Order = 9)] public WorkflowPersistenceBehavior PersistenceBehavior { get; set;}
[DataMember(Order = 10)] public bool DeleteCompletedInstances { get; set;}
/// <summary>
/// A dictionary to store application-specific properties for a given workflow.
/// </summary>
[DataMember(Order = 12)]
[DataMember(Order = 11)]
public Variables CustomAttributes { get; set;} = new();
[DataMember(Order = 13)] public string? DisplayName { get; set; }
[DataMember(Order = 12)] public string? DisplayName { get; set; }
}
}

View file

@ -20,8 +20,10 @@ namespace Elsa.Builders
IOutcomeBuilder When(string outcome);
IActivityBuilder Then(IActivityBuilder targetActivity);
IConnectionBuilder Then(string activityName);
IActivityBuilder WithId(string? id);
IActivityBuilder WithName(string? name);
IActivityBuilder WithId(string? value);
IActivityBuilder WithName(string? value);
IActivityBuilder WithDisplayName(string? value);
IActivityBuilder WithDescription(string? value);
IActivityBuilder LoadWorkflowContext(bool value = true);
IActivityBuilder SaveWorkflowContext(bool value = true);
}

View file

@ -10,6 +10,7 @@
string id,
string? name,
string? displayName,
string? description,
string type,
bool persistWorkflow,
bool loadWorkflowContext,
@ -18,6 +19,7 @@
Id = id;
Name = name;
DisplayName = displayName;
Description = description;
Type = type;
PersistWorkflow = persistWorkflow;
LoadWorkflowContext = loadWorkflowContext;
@ -27,6 +29,7 @@
public string Id { get; set; } = default!;
public string? Name { get; set; }
public string? DisplayName { get; }
public string? Description { get; }
public string Type { get; set; } = default!;
public bool PersistWorkflow { get; set; }
public bool LoadWorkflowContext { get; set; }

View file

@ -15,10 +15,11 @@ namespace Elsa.Services.Models
string id,
string? name,
string? displayName,
string? description,
string type,
bool persistWorkflow,
bool loadWorkflowContext,
bool saveWorkflowContext) : base(id, name, displayName, type, persistWorkflow, loadWorkflowContext, saveWorkflowContext)
bool saveWorkflowContext) : base(id, name, displayName, description, type, persistWorkflow, loadWorkflowContext, saveWorkflowContext)
{
}

View file

@ -5,6 +5,7 @@
string Id { get; }
string? Name { get; }
string? DisplayName { get; }
string? Description { get; }
string Type { get; }
bool PersistWorkflow { get; }
bool LoadWorkflowContext { get; set; }

View file

@ -31,7 +31,7 @@ namespace Elsa.Services.Models
bool deleteCompletedInstances,
IEnumerable<IActivityBlueprint> activities,
IEnumerable<IConnection> connections,
IActivityPropertyProviders activityPropertyValueProviders) : base(id, name, displayName, id, true, false, false)
IActivityPropertyProviders activityPropertyValueProviders) : base(id, name, displayName, description, id, true, false, false)
{
Id = id;
Version = version;
@ -44,7 +44,6 @@ namespace Elsa.Services.Models
Variables = variables ?? new Variables();
CustomAttributes = customAttributes ?? new Variables();
Name = name;
Description = description;
PersistenceBehavior = persistenceBehavior;
DeleteCompletedInstances = deleteCompletedInstances;
Activities = activities.ToList();
@ -56,7 +55,6 @@ namespace Elsa.Services.Models
public string? TenantId { get; set; }
public bool IsSingleton { get; set; }
public bool IsEnabled { get; set; }
public string? Description { get; set; }
public bool IsPublished { get; set; }
public bool IsLatest { get; set; }
public Variables Variables { get; set; }

View file

@ -60,21 +60,27 @@ namespace Elsa.Builders
() => this,
() => WorkflowBuilder.Activities.First(x => x.Name == activityName));
public IActivityBuilder WithId(string? id)
public IActivityBuilder WithId(string? value)
{
ActivityId = id!;
ActivityId = value!;
return this;
}
public IActivityBuilder WithName(string? name)
public IActivityBuilder WithName(string? value)
{
Name = name;
Name = value;
return this;
}
public IActivityBuilder WithDisplay(string? name)
public IActivityBuilder WithDisplayName(string? value)
{
Name = name;
DisplayName = value;
return this;
}
public IActivityBuilder WithDescription(string? value)
{
Description = value;
return this;
}

View file

@ -189,8 +189,8 @@ namespace Elsa.Builders
{
var isComposite = typeof(CompositeActivity).IsAssignableFrom(builder.ActivityType);
return isComposite
? new CompositeActivityBlueprint(builder.ActivityId, builder.Name, builder.DisplayName, builder.ActivityType.Name, builder.PersistWorkflow, builder.LoadWorkflowContextEnabled, builder.SaveWorkflowContextEnabled)
: new ActivityBlueprint(builder.ActivityId, builder.Name, builder.DisplayName, builder.ActivityType.Name, builder.PersistWorkflow, builder.LoadWorkflowContextEnabled, builder.SaveWorkflowContextEnabled);
? new CompositeActivityBlueprint(builder.ActivityId, builder.Name, builder.DisplayName, builder.Description, builder.ActivityType.Name, builder.PersistWorkflow, builder.LoadWorkflowContextEnabled, builder.SaveWorkflowContextEnabled)
: new ActivityBlueprint(builder.ActivityId, builder.Name, builder.DisplayName, builder.Description, builder.ActivityType.Name, builder.PersistWorkflow, builder.LoadWorkflowContextEnabled, builder.SaveWorkflowContextEnabled);
}
}
}

View file

@ -118,6 +118,8 @@ namespace Elsa
WorkflowFactory.Add(workflow.GetType(), workflow);
return this;
}
public ElsaOptions AddWorkflowsFrom<T>() => AddWorkflowsFrom(typeof(T).Assembly);
public ElsaOptions AddWorkflowsFrom(Assembly assembly)
{

View file

@ -1,4 +1,6 @@
using System;
using ElsaDashboard.Components;
using ElsaDashboard.Extensions;
using Microsoft.AspNetCore.Components;
namespace ElsaDashboard.Models
@ -8,5 +10,12 @@ namespace ElsaDashboard.Models
public string ActivityType { get; init; } = default!;
public Func<ActivityDisplayContext, RenderFragment>? RenderBody { get; init; }
public Func<ActivityDisplayContext, RenderFragment>? RenderIcon { get; init; }
public static ActivityDisplayDescriptor For<T>(string activityType) where T : ActivityDisplayComponent =>
new()
{
ActivityType = activityType,
RenderBody = context => builder => builder.AddActivityDisplayComponent<T>(context)
};
}
}

View file

@ -0,0 +1,3 @@
@inherits ActivityDisplayComponent
<p>Output &quot;<a href="#" class="font-medium border-b border-solid border-gray-200 text-black">@(DisplayContext.Properties.Get<string>("Text"))</a>&quot;</p>

View file

@ -0,0 +1,3 @@
@inherits ActivityDisplayComponent
<p>Every <a href="#" class="font-medium border-b border-solid border-gray-200 text-black">@(DisplayContext.Properties.Get<string>("CronExpression"))</a></p>

View file

@ -0,0 +1,4 @@
@using NodaTime
@inherits ActivityDisplayComponent
<p>Start At <a href="#" class="font-medium border-b border-solid border-gray-200 text-black">@(DisplayContext.Properties.Get<Instant>("Instant"))</a></p>

View file

@ -0,0 +1,15 @@
using System.Collections.Generic;
using ElsaDashboard.Application.Activities.Console;
using ElsaDashboard.Models;
using ElsaDashboard.Services;
namespace ElsaDashboard.Application.Display
{
public class ConsoleDisplayProvider : ActivityDisplayProvider
{
protected override IEnumerable<ActivityDisplayDescriptor> GetDescriptors()
{
yield return ActivityDisplayDescriptor.For<WriteLineActivity>("WriteLine");
}
}
}

View file

@ -1,20 +1,18 @@
using System.Collections.Generic;
using ElsaDashboard.Application.Activities;
using ElsaDashboard.Application.Activities.Timers;
using ElsaDashboard.Extensions;
using ElsaDashboard.Models;
using ElsaDashboard.Services;
namespace ElsaDashboard.Application.Display
{
public class TimerDisplayProvider : ActivityDisplayProvider
public class TimersDisplayProvider : ActivityDisplayProvider
{
protected override IEnumerable<ActivityDisplayDescriptor> GetDescriptors()
{
yield return new ActivityDisplayDescriptor
{
ActivityType = "Timer",
RenderBody = context => builder => builder.AddActivityDisplayComponent<TimerActivity>(context)
};
yield return ActivityDisplayDescriptor.For<TimerActivity>("Timer");
yield return ActivityDisplayDescriptor.For<CronActivity>("Cron");
}
}
}

View file

@ -1,4 +1,6 @@
using Blazored.Modal;
using ElsaDashboard.Application.Activities;
using ElsaDashboard.Application.Activities.Console;
using ElsaDashboard.Application.Display;
using ElsaDashboard.Application.Services;
using ElsaDashboard.Extensions;
@ -16,7 +18,8 @@ namespace Microsoft.Extensions.DependencyInjection
.AddScoped<IConfirmDialogService, ConfirmDialogService>()
.AddScoped<IFlyoutPanelService, FlyoutPanelService>()
.AddSingleton<IActivityDisplayService, ActivityDisplayService>()
.AddActivityDisplayProvider<TimerDisplayProvider>();
.AddActivityDisplayProvider<TimersDisplayProvider>()
.AddActivityDisplayProvider<ConsoleDisplayProvider>();
}
}
}

View file

@ -57,10 +57,10 @@ namespace ElsaDashboard.Application.Pages.WorkflowRegistry
{
Name = activityBlueprint.Name,
Type = activityBlueprint.Type,
DisplayName = descriptor.DisplayName,
DisplayName = activityBlueprint.DisplayName ?? descriptor.DisplayName,
Outcomes = descriptor.Outcomes,
ActivityId = activityBlueprint.Id,
Description = descriptor.Description,
Description = activityBlueprint.Description ?? descriptor.Description,
Properties = activityBlueprint.Properties,
DisplayDescriptor = displayDescriptor
};

View file

@ -14,6 +14,10 @@ namespace ElsaDashboard.Backend.Rpc
public Task<PagedList<WorkflowBlueprint>> ListAsync(ListWorkflowBlueprintsRequest request, CallContext context = default) =>
_elsaClient.WorkflowRegistry.ListAsync(request.Page, request.PageSize, request.VersionOptions, context.CancellationToken);
public Task<WorkflowBlueprint?> GetById(GetWorkflowBlueprintByIdRequest request, CallContext context = default) => _elsaClient.WorkflowRegistry.GetByIdAsync(request.Id, request.VersionOptions, context.CancellationToken);
public async Task<WorkflowBlueprint?> GetById(GetWorkflowBlueprintByIdRequest request, CallContext context = default)
{
var result = await _elsaClient.WorkflowRegistry.GetByIdAsync(request.Id, request.VersionOptions, context.CancellationToken);
return result;
}
}
}

View file

@ -37,13 +37,15 @@ namespace Elsa.Server.Api.Endpoints.WorkflowRegistry
{
public string Id { get; set; } = default!;
public string? Name { get; set; }
public string? DisplayName { get; set; }
public string? Description { get; set; }
public string Type { get; set; } = default!;
public bool PersistWorkflow { get; set; }
public bool LoadWorkflowContext { get; set; }
public bool SaveWorkflowContext { get; set; }
public Variables Properties { get; set; } = new();
}
public class WorkflowBlueprintSummaryModel
{
public string Id { get; set; } = default!;

View file

@ -16,6 +16,8 @@ namespace Elsa.Server.Api.Mapping
{
Id = source.Id,
Name = source.Name,
DisplayName = source.DisplayName,
Description = source.Description,
Type = source.Type,
PersistWorkflow = source.PersistWorkflow,
LoadWorkflowContext = source.LoadWorkflowContext,

View file

@ -32,11 +32,7 @@ namespace Elsa.Server.Host
.AddHttpActivities(elsaSection.GetSection("Http").Bind)
.AddEmailActivities(elsaSection.GetSection("Smtp").Bind)
.AddQuartzTimerActivities()
.AddWorkflow<HelloWorld>()
.AddWorkflow<HelloWorldV2>()
.AddWorkflow<GoodbyeWorld>()
.AddWorkflow<NamingWorkflow>()
.AddWorkflow<ConditionWorkflow>()
.AddWorkflowsFrom<Startup>()
);
services

View file

@ -14,15 +14,14 @@ namespace Elsa.Server.Host.Workflows
{
workflow
.WithDisplayName("Conditions")
.Then(() => Console.WriteLine("What is your age?"))
.Then(() => Console.WriteLine("What is your age?")).WithDisplayName("Write").WithDescription("What is your age?")
.ReadLine()
.Timer(Duration.FromMinutes(5))
.SetVariable("Age", context => int.Parse(context.GetInput<string>()))
.IfElse(context => context.GetVariable<int>("Age") < 18, ifElse =>
{
ifElse.When(OutcomeNames.True).WriteLine("You are not allowed to drink beer.");
ifElse.When(OutcomeNames.False).WriteLine("Enjoy your beer!");
});
.IfElse(
context => context.GetVariable<int>("Age") < 18,
whenTrue => whenTrue.WriteLine("You are not allowed to drink beer."),
whenFalse => whenFalse.WriteLine("Enjoy your beer!"));
}
}
}