Merge remote-tracking branch 'origin/patch/3.2.x'
This commit is contained in:
commit
88f657e940
4
.github/workflows/elsa-server-and-studio.yml
vendored
4
.github/workflows/elsa-server-and-studio.yml
vendored
|
|
@ -3,7 +3,7 @@ on:
|
|||
workflow_dispatch:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
- patch/3.2.x
|
||||
|
||||
jobs:
|
||||
push_to_registry:
|
||||
|
|
@ -29,7 +29,7 @@ jobs:
|
|||
with:
|
||||
# list of Docker images to use as base name for tags
|
||||
images: |
|
||||
elsaworkflows/elsa-server-and-studio-v3
|
||||
elsaworkflows/elsa-server-and-studio-v3-2-0-rc3
|
||||
flavor: |
|
||||
latest=true
|
||||
# generate Docker tags based on the following events/attributes
|
||||
|
|
|
|||
4
.github/workflows/elsa-server.yml
vendored
4
.github/workflows/elsa-server.yml
vendored
|
|
@ -3,7 +3,7 @@ on:
|
|||
workflow_dispatch:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
- patch/3.2.x
|
||||
|
||||
jobs:
|
||||
push_to_registry:
|
||||
|
|
@ -29,7 +29,7 @@ jobs:
|
|||
with:
|
||||
# list of Docker images to use as base name for tags
|
||||
images: |
|
||||
elsaworkflows/elsa-server-v3
|
||||
elsaworkflows/elsa-server-v3-2-0-rc3
|
||||
flavor: |
|
||||
latest=true
|
||||
# generate Docker tags based on the following events/attributes
|
||||
|
|
|
|||
4
.github/workflows/elsa-studio.yml
vendored
4
.github/workflows/elsa-studio.yml
vendored
|
|
@ -3,7 +3,7 @@ on:
|
|||
workflow_dispatch:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
- patch/3.2.x
|
||||
|
||||
jobs:
|
||||
push_to_registry:
|
||||
|
|
@ -29,7 +29,7 @@ jobs:
|
|||
with:
|
||||
# list of Docker images to use as base name for tags
|
||||
images: |
|
||||
elsaworkflows/elsa-studio-v3
|
||||
elsaworkflows/elsa-studio-v3-2-0-rc3
|
||||
flavor: |
|
||||
latest=true
|
||||
# generate Docker tags based on the following events/attributes
|
||||
|
|
|
|||
|
|
@ -1,34 +1,35 @@
|
|||
<Project>
|
||||
<PropertyGroup>
|
||||
<Authors>Elsa Workflows Community</Authors>
|
||||
<Copyright>2023</Copyright>
|
||||
<PropertyGroup>
|
||||
<Authors>Elsa Workflows Community</Authors>
|
||||
<Copyright>2023</Copyright>
|
||||
|
||||
<PackageProjectUrl>https://github.com/elsa-workflows/elsa-core</PackageProjectUrl>
|
||||
<RepositoryUrl>https://github.com/elsa-workflows/elsa-core</RepositoryUrl>
|
||||
<RepositoryType>git</RepositoryType>
|
||||
<PackageProjectUrl>https://github.com/elsa-workflows/elsa-core</PackageProjectUrl>
|
||||
<RepositoryUrl>https://github.com/elsa-workflows/elsa-core</RepositoryUrl>
|
||||
<RepositoryType>git</RepositoryType>
|
||||
|
||||
<LangVersion>latest</LangVersion>
|
||||
<Nullable>enable</Nullable>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<LangVersion>latest</LangVersion>
|
||||
<Nullable>enable</Nullable>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
|
||||
<PackageLicenseExpression>MIT</PackageLicenseExpression>
|
||||
<PackageIcon>icon.png</PackageIcon>
|
||||
<PackageLicenseExpression>MIT</PackageLicenseExpression>
|
||||
<PackageIcon>icon.png</PackageIcon>
|
||||
|
||||
<!-- For NuGet browsers that currently don't support <PackageIcon> yet -->
|
||||
<PackageIconUrl>https://v3.elsaworkflows.io/nuget-icon.png</PackageIconUrl>
|
||||
|
||||
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||
<AnalysisModeDocumentation>Default</AnalysisModeDocumentation>
|
||||
<AnalysisLevelDocumentation>latest</AnalysisLevelDocumentation>
|
||||
<!-- For NuGet browsers that currently don't support <PackageIcon> yet -->
|
||||
<PackageIconUrl>https://v3.elsaworkflows.io/nuget-icon.png</PackageIconUrl>
|
||||
|
||||
<!-- https://github.com/dotnet/sourcelink -->
|
||||
<IncludeSymbols>true</IncludeSymbols>
|
||||
<SymbolPackageFormat>snupkg</SymbolPackageFormat>
|
||||
<EnableTrimAnalyzer>false</EnableTrimAnalyzer>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<NoWarn>$(NoWarn);CS0162;CS1591</NoWarn>
|
||||
</PropertyGroup>
|
||||
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||
<AnalysisModeDocumentation>Default</AnalysisModeDocumentation>
|
||||
<AnalysisLevelDocumentation>latest</AnalysisLevelDocumentation>
|
||||
|
||||
<!-- https://github.com/dotnet/sourcelink -->
|
||||
<IncludeSymbols>true</IncludeSymbols>
|
||||
<SymbolPackageFormat>snupkg</SymbolPackageFormat>
|
||||
<EnableTrimAnalyzer>true</EnableTrimAnalyzer>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<NoWarn>$(NoWarn);CS0162;CS1591</NoWarn>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<ElsaStudioVersion>3.2.0-rc3.417</ElsaStudioVersion>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
|
|
@ -23,9 +23,9 @@
|
|||
<PackageVersion Include="DistributedLock.Postgres" Version="1.1.0" />
|
||||
<PackageVersion Include="DistributedLock.Redis" Version="1.0.3" />
|
||||
<PackageVersion Include="Elastic.Clients.Elasticsearch" Version="8.14.0" />
|
||||
<PackageVersion Include="Elsa.Studio" Version="3.2.0-rc2.369" />
|
||||
<PackageVersion Include="Elsa.Studio.Core.BlazorWasm" Version="3.2.0-rc2.369" />
|
||||
<PackageVersion Include="Elsa.Studio.Login.BlazorWasm" Version="3.2.0-rc2.369" />
|
||||
<PackageVersion Include="Elsa.Studio" Version="$(ElsaStudioVersion)" />
|
||||
<PackageVersion Include="Elsa.Studio.Core.BlazorWasm" Version="$(ElsaStudioVersion)" />
|
||||
<PackageVersion Include="Elsa.Studio.Login.BlazorWasm" Version="$(ElsaStudioVersion)" />
|
||||
<PackageVersion Include="FastEndpoints" Version="5.26.0" />
|
||||
<PackageVersion Include="FastEndpoints.Security" Version="5.26.0" />
|
||||
<PackageVersion Include="FastEndpoints.Swagger" Version="5.26.0" />
|
||||
|
|
|
|||
|
|
@ -10,20 +10,20 @@
|
|||
<ProjectReference Include="..\..\bundles\Elsa\Elsa.csproj"/>
|
||||
<ProjectReference Include="..\..\modules\Elsa.Caching.Distributed.MassTransit\Elsa.Caching.Distributed.MassTransit.csproj" />
|
||||
<ProjectReference Include="..\..\modules\Elsa.Caching.Distributed\Elsa.Caching.Distributed.csproj" />
|
||||
<ProjectReference Include="..\..\modules\Elsa.CSharp\Elsa.CSharp.csproj" />
|
||||
<ProjectReference Include="..\..\modules\Elsa.CSharp\Elsa.CSharp.csproj"/>
|
||||
<ProjectReference Include="..\..\modules\Elsa.Email\Elsa.Email.csproj"/>
|
||||
<ProjectReference Include="..\..\modules\Elsa.EntityFrameworkCore.MySql\Elsa.EntityFrameworkCore.MySql.csproj" />
|
||||
<ProjectReference Include="..\..\modules\Elsa.EntityFrameworkCore.MySql\Elsa.EntityFrameworkCore.MySql.csproj"/>
|
||||
<ProjectReference Include="..\..\modules\Elsa.EntityFrameworkCore.Sqlite\Elsa.EntityFrameworkCore.Sqlite.csproj"/>
|
||||
<ProjectReference Include="..\..\modules\Elsa.Hangfire\Elsa.Hangfire.csproj"/>
|
||||
<ProjectReference Include="..\..\modules\Elsa.Http\Elsa.Http.csproj"/>
|
||||
<ProjectReference Include="..\..\modules\Elsa.Identity\Elsa.Identity.csproj"/>
|
||||
<ProjectReference Include="..\..\modules\Elsa.Liquid\Elsa.Liquid.csproj"/>
|
||||
<ProjectReference Include="..\..\modules\Elsa.EntityFrameworkCore\Elsa.EntityFrameworkCore.csproj"/>
|
||||
<ProjectReference Include="..\..\modules\Elsa.MassTransit.AzureServiceBus\Elsa.MassTransit.AzureServiceBus.csproj" />
|
||||
<ProjectReference Include="..\..\modules\Elsa.MassTransit.RabbitMq\Elsa.MassTransit.RabbitMq.csproj" />
|
||||
<ProjectReference Include="..\..\modules\Elsa.MassTransit\Elsa.MassTransit.csproj" />
|
||||
<ProjectReference Include="..\..\modules\Elsa.ProtoActor\Elsa.ProtoActor.csproj" />
|
||||
<ProjectReference Include="..\..\modules\Elsa.Python\Elsa.Python.csproj" />
|
||||
<ProjectReference Include="..\..\modules\Elsa.MassTransit.AzureServiceBus\Elsa.MassTransit.AzureServiceBus.csproj"/>
|
||||
<ProjectReference Include="..\..\modules\Elsa.MassTransit.RabbitMq\Elsa.MassTransit.RabbitMq.csproj"/>
|
||||
<ProjectReference Include="..\..\modules\Elsa.MassTransit\Elsa.MassTransit.csproj"/>
|
||||
<ProjectReference Include="..\..\modules\Elsa.ProtoActor\Elsa.ProtoActor.csproj"/>
|
||||
<ProjectReference Include="..\..\modules\Elsa.Python\Elsa.Python.csproj"/>
|
||||
<ProjectReference Include="..\..\modules\Elsa.Quartz\Elsa.Quartz.csproj"/>
|
||||
<ProjectReference Include="..\..\modules\Elsa.Webhooks\Elsa.Webhooks.csproj"/>
|
||||
<ProjectReference Include="..\..\modules\Elsa.Workflows.Api\Elsa.Workflows.Api.csproj"/>
|
||||
|
|
@ -31,10 +31,10 @@
|
|||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.Server" />
|
||||
<PackageReference Include="Proto.Persistence.Sqlite" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.Server"/>
|
||||
<PackageReference Include="Proto.Persistence.Sqlite"/>
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Elsa.Studio"/>
|
||||
<PackageReference Include="Elsa.Studio.Login.BlazorWasm"/>
|
||||
|
|
|
|||
|
|
@ -1,8 +1,6 @@
|
|||
namespace Elsa.ServerAndStudio.Web.Enums;
|
||||
|
||||
/// <summary>
|
||||
/// Represents the transport options for distributed caching.
|
||||
/// </summary>
|
||||
public enum DistributedCachingTransport
|
||||
{
|
||||
None,
|
||||
|
|
|
|||
|
|
@ -1,8 +1,6 @@
|
|||
namespace Elsa.ServerAndStudio.Web.Enums;
|
||||
|
||||
/// <summary>
|
||||
/// Represents the type of messaging broker used in MassTransit.
|
||||
/// </summary>
|
||||
public enum MassTransitBroker
|
||||
{
|
||||
Memory,
|
||||
|
|
|
|||
|
|
@ -13,8 +13,4 @@
|
|||
<PackageReference Include="Microsoft.Extensions.Http" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<_ContentIncludedByDefault Remove="wwwroot\index.html" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,41 @@
|
|||
using System.Text.Json;
|
||||
using Elsa.Api.Client.Shared.Models;
|
||||
|
||||
namespace Elsa.Api.Client.Extensions;
|
||||
|
||||
/// <summary>
|
||||
/// Provides extension methods for the PropertyBag class.
|
||||
/// </summary>
|
||||
public static class PropertyBagExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Tries to retrieve a value from the PropertyBag based on the provided key.
|
||||
/// If the specified key does not exist in the PropertyBag, the method will return the default value obtained from the defaultValue function.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of the value to retrieve.</typeparam>
|
||||
/// <param name="propertyBag">The PropertyBag to retrieve the value from.</param>
|
||||
/// <param name="key">The key of the value to retrieve.</param>
|
||||
/// <param name="defaultValue">A function that returns the default value to be returned if the key does not exist in the PropertyBag.</param>
|
||||
/// <returns>The value associated with the key, or the default value if the key does not exist.</returns>
|
||||
public static T TryGetValueOrDefault<T>(this PropertyBag propertyBag, string key, Func<T> defaultValue)
|
||||
{
|
||||
if (!propertyBag.TryGetValue(key, out var value))
|
||||
return defaultValue();
|
||||
|
||||
var json = (string)value;
|
||||
return JsonSerializer.Deserialize<T>(json);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets a value in the PropertyBag based on the provided key.
|
||||
/// The value is serialized using JSON.
|
||||
/// </summary>
|
||||
/// <param name="propertyBag">The PropertyBag to set the value in.</param>
|
||||
/// <param name="key">The key to associate with the value.</param>
|
||||
/// <param name="value">The value to store in the PropertyBag.</param>
|
||||
public static void SetValue(this PropertyBag propertyBag, string key, object value)
|
||||
{
|
||||
var json = JsonSerializer.Serialize(value);
|
||||
propertyBag[key] = json;
|
||||
}
|
||||
}
|
||||
|
|
@ -209,6 +209,7 @@ public interface IWorkflowDefinitionsApi
|
|||
/// <param name="definitionId">The definition ID of the workflow definition to revert.</param>
|
||||
/// <param name="version">The version to revert to.</param>
|
||||
/// <param name="cancellationToken">An optional cancellation token.</param>
|
||||
/// <returns>A summary view of the newly created workflow definition version.</returns>
|
||||
[Post("/workflow-definitions/{definitionId}/revert/{version}")]
|
||||
Task RevertVersionAsync(string definitionId, int version, CancellationToken cancellationToken = default);
|
||||
Task<WorkflowDefinitionSummary> RevertVersionAsync(string definitionId, int version, CancellationToken cancellationToken = default);
|
||||
}
|
||||
|
|
@ -58,6 +58,11 @@ public class WorkflowDefinition : LinkedEntity
|
|||
/// </summary>
|
||||
public IDictionary<string, object> CustomProperties { get; set; } = new Dictionary<string, object>();
|
||||
|
||||
/// <summary>
|
||||
/// Stores custom information about the workflow. Can be used to store application-specific properties to associate with the workflow.
|
||||
/// </summary>
|
||||
public PropertyBag PropertyBag { get; set; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// The name of the workflow provider that created this workflow, if any.
|
||||
/// </summary>
|
||||
|
|
|
|||
|
|
@ -55,6 +55,11 @@ public class WorkflowDefinitionModel : LinkedEntity
|
|||
/// </summary>
|
||||
public IDictionary<string, object>? CustomProperties { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Stores custom information about the workflow. Can be used to store application-specific properties to associate with the workflow.
|
||||
/// </summary>
|
||||
public PropertyBag PropertyBag { get; set; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets whether the workflow definition is read-only.
|
||||
/// </summary>
|
||||
|
|
|
|||
|
|
@ -1,22 +1,17 @@
|
|||
namespace Elsa.Api.Client.Resources.WorkflowInstances.Requests;
|
||||
|
||||
/// <summary>
|
||||
/// Represents a request to list journal records.
|
||||
/// </summary>
|
||||
public class JournalFilter
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the activity IDs to filter by.
|
||||
/// </summary>
|
||||
public ICollection<string>? ActivityIds { get; set; }
|
||||
|
||||
/// <summary>
|
||||
|
||||
/// Gets or sets the activity node IDs to filter by.
|
||||
public ICollection<string>? ActivityNodeIds { get; set; }
|
||||
|
||||
/// Gets or sets the activity types to filter out.
|
||||
/// </summary>
|
||||
public ICollection<string>? ExcludedActivityTypes { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the event types to filter by.
|
||||
/// </summary>
|
||||
public ICollection<string>? EventNames { get; set; }
|
||||
}
|
||||
20
src/clients/Elsa.Api.Client/Shared/Models/PropertyBag.cs
Normal file
20
src/clients/Elsa.Api.Client/Shared/Models/PropertyBag.cs
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace Elsa.Api.Client.Shared.Models;
|
||||
|
||||
/// A dictionary of values that is skipped by polymorphic serialization.
|
||||
public class PropertyBag : Dictionary<string, object>
|
||||
{
|
||||
/// <inheritdoc />
|
||||
[JsonConstructor]
|
||||
public PropertyBag() : base(StringComparer.OrdinalIgnoreCase)
|
||||
{
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public PropertyBag(IDictionary<string, object> dictionary) : this()
|
||||
{
|
||||
foreach (var kvp in dictionary)
|
||||
Add(kvp.Key, kvp.Value);
|
||||
}
|
||||
}
|
||||
|
|
@ -21,4 +21,5 @@ public class WrappedInput
|
|||
/// Gets or sets the memory reference of this input.
|
||||
/// </summary>
|
||||
public MemoryReference MemoryReference { get; set; } = default!;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
67
src/modules/Elsa.Common/Extensions/PropertyBagExtensions.cs
Normal file
67
src/modules/Elsa.Common/Extensions/PropertyBagExtensions.cs
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
using System.Text.Json;
|
||||
using Elsa.Common.Models;
|
||||
|
||||
// ReSharper disable once CheckNamespace
|
||||
namespace Elsa.Extensions;
|
||||
|
||||
/// <summary>
|
||||
/// Provides extension methods for the PropertyBag class.
|
||||
/// </summary>
|
||||
public static class PropertyBagExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Tries to retrieve a value from the PropertyBag based on the provided key.
|
||||
/// If the specified key does not exist in the PropertyBag, the method will return the default value obtained from the defaultValue function.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of the value to retrieve.</typeparam>
|
||||
/// <param name="propertyBag">The PropertyBag to retrieve the value from.</param>
|
||||
/// <param name="key">The key of the value to retrieve.</param>
|
||||
/// <param name="defaultValue">A function that returns the default value to be returned if the key does not exist in the PropertyBag.</param>
|
||||
/// <param name="options">Optional JSON serializer options.</param>
|
||||
/// <returns>The value associated with the key, or the default value if the key does not exist.</returns>
|
||||
public static T TryGetValueOrDefault<T>(this PropertyBag propertyBag, string key, Func<T> defaultValue, JsonSerializerOptions? options = null)
|
||||
{
|
||||
if (!propertyBag.TryGetValue(key, out var value))
|
||||
return defaultValue();
|
||||
|
||||
var json = (string)value;
|
||||
return JsonSerializer.Deserialize<T>(json, options);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tries to retrieve a value from the PropertyBag based on the provided key.
|
||||
/// If the specified key does not exist in the PropertyBag, the method will return the default value obtained from the defaultValue function.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of the value to retrieve.</typeparam>
|
||||
/// <param name="propertyBag">The PropertyBag to retrieve the value from.</param>
|
||||
/// <param name="key">The key of the value to retrieve.</param>
|
||||
/// <param name="value">The deserialized value.</param>
|
||||
/// <param name="options">Optional JSON serializer options.</param>
|
||||
/// <returns>True if the value exists, false otherwise.</returns>
|
||||
public static bool TryGetValue<T>(this PropertyBag propertyBag, string key, out T value, JsonSerializerOptions? options = null)
|
||||
{
|
||||
if (!propertyBag.TryGetValue(key, out var v))
|
||||
{
|
||||
value = default!;
|
||||
return false;
|
||||
}
|
||||
|
||||
var json = (string)v;
|
||||
value = JsonSerializer.Deserialize<T>(json, options);
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets a value in the PropertyBag based on the provided key.
|
||||
/// The value is serialized using JSON.
|
||||
/// </summary>
|
||||
/// <param name="propertyBag">The PropertyBag to set the value in.</param>
|
||||
/// <param name="key">The key to associate with the value.</param>
|
||||
/// <param name="value">The value to store in the PropertyBag.</param>
|
||||
/// /// <param name="options">Optional JSON serializer options.</param>
|
||||
public static void SetValue(this PropertyBag propertyBag, string key, object value, JsonSerializerOptions? options = null)
|
||||
{
|
||||
var json = JsonSerializer.Serialize(value);
|
||||
propertyBag[key] = json;
|
||||
}
|
||||
}
|
||||
20
src/modules/Elsa.Common/Models/PropertyBag.cs
Normal file
20
src/modules/Elsa.Common/Models/PropertyBag.cs
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace Elsa.Common.Models;
|
||||
|
||||
/// A dictionary of values that is skipped by polymorphic serialization.
|
||||
public class PropertyBag : Dictionary<string, object>
|
||||
{
|
||||
/// <inheritdoc />
|
||||
[JsonConstructor]
|
||||
public PropertyBag() : base(StringComparer.OrdinalIgnoreCase)
|
||||
{
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public PropertyBag(IDictionary<string, object> dictionary) : this()
|
||||
{
|
||||
foreach (var kvp in dictionary)
|
||||
Add(kvp.Key, kvp.Value);
|
||||
}
|
||||
}
|
||||
|
|
@ -115,4 +115,4 @@ public struct VersionOptions
|
|||
/// Returns a simple string representation of this <see cref="VersionOptions"/>.
|
||||
/// </summary>
|
||||
public override string ToString() => AllVersions ? "AllVersions" : IsDraft ? "Draft" : IsLatest ? "Latest" : IsPublished ? "Published" : IsLatestOrPublished ? "LatestOrPublished" : IsLatestAndPublished ? "LatestAndPublished" : Version.ToString(CultureInfo.InvariantCulture);
|
||||
}
|
||||
}
|
||||
|
|
@ -26,7 +26,6 @@ public class RunMigrationsHostedService<TDbContext> : IHostedService where TDbCo
|
|||
var dbContextFactory = scope.ServiceProvider.GetRequiredService<IDbContextFactory<TDbContext>>();
|
||||
await using var dbContext = await dbContextFactory.CreateDbContextAsync(cancellationToken);
|
||||
await dbContext.Database.MigrateAsync(cancellationToken);
|
||||
await dbContext.DisposeAsync();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ internal class Configurations : IEntityTypeConfiguration<WorkflowDefinition>, IE
|
|||
builder.Ignore(x => x.Outputs);
|
||||
builder.Ignore(x => x.Outcomes);
|
||||
builder.Ignore(x => x.CustomProperties);
|
||||
builder.Ignore(x => x.PropertyBag);
|
||||
builder.Ignore(x => x.Options);
|
||||
builder.Property<string>("Data");
|
||||
builder.Property<bool?>("UsableAsActivity");
|
||||
|
|
|
|||
|
|
@ -177,8 +177,8 @@ public class EFCoreWorkflowDefinitionStore(EntityStore<ManagementElsaDbContext,
|
|||
|
||||
private ValueTask OnSaveAsync(ManagementElsaDbContext managementElsaDbContext, WorkflowDefinition entity, CancellationToken cancellationToken)
|
||||
{
|
||||
var data = new WorkflowDefinitionState(entity.Options, entity.Variables, entity.Inputs, entity.Outputs, entity.Outcomes, entity.CustomProperties);
|
||||
var json = payloadSerializer.Serialize(data);
|
||||
var data = new WorkflowDefinitionState(entity.Options, entity.Variables, entity.Inputs, entity.Outputs, entity.Outcomes, entity.CustomProperties, entity.PropertyBag);
|
||||
var json = _payloadSerializer.Serialize(data);
|
||||
|
||||
managementElsaDbContext.Entry(entity).Property("Data").CurrentValue = json;
|
||||
managementElsaDbContext.Entry(entity).Property("UsableAsActivity").CurrentValue = data.Options.UsableAsActivity;
|
||||
|
|
@ -190,7 +190,7 @@ public class EFCoreWorkflowDefinitionStore(EntityStore<ManagementElsaDbContext,
|
|||
if (entity == null)
|
||||
return ValueTask.CompletedTask;
|
||||
|
||||
var data = new WorkflowDefinitionState(entity.Options, entity.Variables, entity.Inputs, entity.Outputs, entity.Outcomes, entity.CustomProperties);
|
||||
var data = new WorkflowDefinitionState(entity.Options, entity.Variables, entity.Inputs, entity.Outputs, entity.Outcomes, entity.CustomProperties, entity.PropertyBag);
|
||||
var json = (string?)managementElsaDbContext.Entry(entity).Property("Data").CurrentValue;
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(json))
|
||||
|
|
@ -202,6 +202,7 @@ public class EFCoreWorkflowDefinitionStore(EntityStore<ManagementElsaDbContext,
|
|||
entity.Outputs = data.Outputs;
|
||||
entity.Outcomes = data.Outcomes;
|
||||
entity.CustomProperties = data.CustomProperties;
|
||||
entity.PropertyBag = data.PropertyBag;
|
||||
|
||||
return ValueTask.CompletedTask;
|
||||
}
|
||||
|
|
@ -254,7 +255,8 @@ public class EFCoreWorkflowDefinitionStore(EntityStore<ManagementElsaDbContext,
|
|||
ICollection<InputDefinition> inputs,
|
||||
ICollection<OutputDefinition> outputs,
|
||||
ICollection<string> outcomes,
|
||||
IDictionary<string, object> customProperties
|
||||
IDictionary<string, object> customProperties,
|
||||
PropertyBag propertyBag
|
||||
)
|
||||
{
|
||||
Options = options;
|
||||
|
|
@ -263,6 +265,7 @@ public class EFCoreWorkflowDefinitionStore(EntityStore<ManagementElsaDbContext,
|
|||
Outputs = outputs;
|
||||
Outcomes = outcomes;
|
||||
CustomProperties = customProperties;
|
||||
PropertyBag = propertyBag;
|
||||
}
|
||||
|
||||
public WorkflowOptions Options { get; set; } = new();
|
||||
|
|
@ -270,6 +273,10 @@ public class EFCoreWorkflowDefinitionStore(EntityStore<ManagementElsaDbContext,
|
|||
public ICollection<InputDefinition> Inputs { get; set; } = new List<InputDefinition>();
|
||||
public ICollection<OutputDefinition> Outputs { get; set; } = new List<OutputDefinition>();
|
||||
public ICollection<string> Outcomes { get; set; } = new List<string>();
|
||||
|
||||
[Obsolete("Use PropertyBag instead")]
|
||||
public IDictionary<string, object> CustomProperties { get; set; } = new Dictionary<string, object>();
|
||||
|
||||
public PropertyBag PropertyBag { get; set; } = new();
|
||||
}
|
||||
}
|
||||
|
|
@ -24,16 +24,17 @@ public class ExpressionOptions
|
|||
this.AddTypeAlias<bool>("Boolean");
|
||||
this.AddTypeAlias<decimal>("Decimal");
|
||||
this.AddTypeAlias<double>("Double");
|
||||
this.AddTypeAlias<byte[]>("ByteArray");
|
||||
this.AddTypeAlias<Guid>("Guid");
|
||||
this.AddTypeAlias<DateTime>("DateTime");
|
||||
this.AddTypeAlias<DateTimeOffset>("DateTimeOffset");
|
||||
this.AddTypeAlias<TimeSpan>("TimeSpan");
|
||||
this.AddTypeAlias<ExpandoObject>("ExpandoObject");
|
||||
this.AddTypeAlias<Stream>("Stream");
|
||||
this.AddTypeAlias<ExpandoObject>("JSON");
|
||||
this.AddTypeAlias<Dictionary<string, string>>("StringDictionary");
|
||||
this.AddTypeAlias<IDictionary<string, string>>("StringDictionary");
|
||||
this.AddTypeAlias<IDictionary<string, object>>("ObjectDictionary");
|
||||
this.AddTypeAlias<Dictionary<string, string>>("StringMap");
|
||||
this.AddTypeAlias<Dictionary<string, object>>("ObjectMap");
|
||||
this.AddTypeAlias<Dictionary<string, object>>("ObjectDictionary");
|
||||
}
|
||||
|
||||
/// Gets the type alias dictionary.
|
||||
|
|
|
|||
|
|
@ -222,6 +222,11 @@ public class HttpFeature : FeatureBase
|
|||
|
||||
Services.Configure<ExpressionOptions>(options =>
|
||||
{
|
||||
options.AddTypeAlias<HttpRequest>("HttpRequest");
|
||||
options.AddTypeAlias<HttpResponse>("HttpResponse");
|
||||
options.AddTypeAlias<HttpResponseMessage>("HttpResponseMessage");
|
||||
options.AddTypeAlias<HttpHeaders>("HttpHeaders");
|
||||
options.AddTypeAlias<RouteData>("RouteData");
|
||||
options.AddTypeAlias<IFormFile>("FormFile");
|
||||
options.AddTypeAlias<IFormFile[]>("FormFile[]");
|
||||
options.AddTypeAlias<HttpFile>("HttpFile");
|
||||
|
|
|
|||
|
|
@ -4,16 +4,16 @@ using Elsa.Workflows.Management.Entities;
|
|||
// ReSharper disable once CheckNamespace
|
||||
namespace Elsa.Extensions;
|
||||
|
||||
/// <summary>
|
||||
/// Adds extension methods to <see cref="WorkflowDefinition"/>.
|
||||
/// </summary>
|
||||
public static class WorkflowDefinitionExtensions
|
||||
public static class WorkflowContextWorkflowDefinitionExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the workflow context provider types that are installed on the workflow definition.
|
||||
/// </summary>
|
||||
/// <param name="workflowDefinition">The workflow definition to get the provider types from.</param>
|
||||
/// <returns>The workflow context provider types.</returns>
|
||||
public static IEnumerable<Type> GetWorkflowContextProviderTypes(this WorkflowDefinition workflowDefinition) =>
|
||||
workflowDefinition.CustomProperties.GetOrAdd(Constants.WorkflowContextProviderTypesKey, () => new List<Type>());
|
||||
public static IEnumerable<Type> GetWorkflowContextProviderTypes(this WorkflowDefinition workflowDefinition)
|
||||
{
|
||||
return workflowDefinition.PropertyBag.GetOrAdd(Constants.WorkflowContextProviderTypesKey, () => new List<Type>());
|
||||
}
|
||||
}
|
||||
|
|
@ -1,36 +1,38 @@
|
|||
using System.Text.Json;
|
||||
using Elsa.Expressions.Contracts;
|
||||
using Elsa.Extensions;
|
||||
using Elsa.WorkflowContexts.Contracts;
|
||||
using Elsa.Workflows;
|
||||
using Elsa.Workflows.Contracts;
|
||||
using Elsa.Workflows.Pipelines.ActivityExecution;
|
||||
using Elsa.Workflows.Serialization.Converters;
|
||||
using JetBrains.Annotations;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace Elsa.WorkflowContexts.Middleware;
|
||||
|
||||
/// <summary>
|
||||
/// Middleware that loads and save workflow context into the currently executing workflow using installed workflow context providers.
|
||||
/// </summary>
|
||||
public class WorkflowContextActivityExecutionMiddleware : IActivityExecutionMiddleware
|
||||
[UsedImplicitly]
|
||||
public class WorkflowContextActivityExecutionMiddleware(ActivityMiddlewareDelegate next, IServiceScopeFactory serviceScopeFactory, IWellKnownTypeRegistry wellKnownTypeRegistry) : IActivityExecutionMiddleware
|
||||
{
|
||||
private readonly ActivityMiddlewareDelegate _next;
|
||||
private readonly IServiceScopeFactory _serviceScopeFactory;
|
||||
|
||||
/// <summary>
|
||||
/// Constructor.
|
||||
/// </summary>
|
||||
public WorkflowContextActivityExecutionMiddleware(ActivityMiddlewareDelegate next, IServiceScopeFactory serviceScopeFactory)
|
||||
private readonly JsonSerializerOptions _jsonSerializerOptions = new JsonSerializerOptions
|
||||
{
|
||||
_next = next;
|
||||
_serviceScopeFactory = serviceScopeFactory;
|
||||
}
|
||||
PropertyNameCaseInsensitive = true
|
||||
}.WithConverters(new TypeJsonConverter(wellKnownTypeRegistry));
|
||||
|
||||
/// <inheritdoc />
|
||||
public async ValueTask InvokeAsync(ActivityExecutionContext context)
|
||||
{
|
||||
// Check if the workflow contains any workflow context providers.
|
||||
if (!context.WorkflowExecutionContext.Workflow.CustomProperties.TryGetValue<ICollection<Type>>(Constants.WorkflowContextProviderTypesKey, out var providerTypes))
|
||||
if (!context.WorkflowExecutionContext.Workflow.PropertyBag.TryGetValue<ICollection<Type>>(Constants.WorkflowContextProviderTypesKey, out var providerTypes, _jsonSerializerOptions))
|
||||
{
|
||||
await _next(context);
|
||||
await next(context);
|
||||
return;
|
||||
}
|
||||
|
||||
if (providerTypes.Count == 0)
|
||||
{
|
||||
await next(context);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -40,12 +42,12 @@ public class WorkflowContextActivityExecutionMiddleware : IActivityExecutionMidd
|
|||
// Is the activity configured to load the context?
|
||||
foreach (var providerType in providerTypes)
|
||||
{
|
||||
// Is the activity configured to load the context or is this a background execution?
|
||||
// Is the activity configured to load the context, or is this a background execution?
|
||||
var load = isBackgroundExecution || context.Activity.GetActivityWorkflowContextSettings(providerType).Load;
|
||||
if (!load) continue;
|
||||
|
||||
// Load the context.
|
||||
using var scope = _serviceScopeFactory.CreateScope();
|
||||
using var scope = serviceScopeFactory.CreateScope();
|
||||
var provider = (IWorkflowContextProvider)ActivatorUtilities.GetServiceOrCreateInstance(scope.ServiceProvider, providerType);
|
||||
var value = await provider.LoadAsync(context.WorkflowExecutionContext);
|
||||
|
||||
|
|
@ -54,7 +56,7 @@ public class WorkflowContextActivityExecutionMiddleware : IActivityExecutionMidd
|
|||
}
|
||||
|
||||
// Invoke the next middleware.
|
||||
await _next(context);
|
||||
await next(context);
|
||||
|
||||
// Invoke each workflow context provider to persists the context.
|
||||
foreach (var providerType in providerTypes)
|
||||
|
|
@ -64,7 +66,7 @@ public class WorkflowContextActivityExecutionMiddleware : IActivityExecutionMidd
|
|||
if (!save) continue;
|
||||
|
||||
// Get the loaded value from the workflow execution context.
|
||||
using var scope = _serviceScopeFactory.CreateScope();
|
||||
using var scope = serviceScopeFactory.CreateScope();
|
||||
var value = context.WorkflowExecutionContext.GetWorkflowContext(providerType);
|
||||
|
||||
// Save the context.
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ using Elsa.Abstractions;
|
|||
using Elsa.Workflows.Management;
|
||||
using Elsa.Workflows.Management.Filters;
|
||||
using JetBrains.Annotations;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
|
||||
namespace Elsa.Workflows.Api.Endpoints.WorkflowDefinitions.GetById;
|
||||
|
||||
|
|
@ -12,6 +13,7 @@ internal class GetById(IWorkflowDefinitionStore store, IWorkflowDefinitionLinker
|
|||
{
|
||||
Get("/workflow-definitions/by-id/{id}");
|
||||
ConfigurePermissions("read:workflow-definitions");
|
||||
Options(x => x.WithName("GetWorkflowDefinitionById"));
|
||||
}
|
||||
|
||||
public override async Task HandleAsync(Request request, CancellationToken cancellationToken)
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ using Elsa.Workflows.Api.Constants;
|
|||
using Elsa.Workflows.Api.Requirements;
|
||||
using Elsa.Workflows.Management;
|
||||
using Elsa.Workflows.Management.Filters;
|
||||
using Elsa.Workflows.Management.Models;
|
||||
using JetBrains.Annotations;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
|
||||
|
|
@ -46,7 +47,12 @@ internal class RevertVersion(IWorkflowDefinitionManager workflowDefinitionManage
|
|||
return;
|
||||
}
|
||||
|
||||
await workflowDefinitionManager.RevertVersionAsync(definitionId, version, cancellationToken);
|
||||
await SendOkAsync(cancellationToken);
|
||||
var newDefinition = await workflowDefinitionManager.RevertVersionAsync(definitionId, version, cancellationToken);
|
||||
var newDefinitionSummary = WorkflowDefinitionSummary.FromDefinition(newDefinition);
|
||||
|
||||
await SendCreatedAtAsync("GetWorkflowDefinitionById", new
|
||||
{
|
||||
id = newDefinition.Id
|
||||
}, newDefinitionSummary, cancellation: cancellationToken);
|
||||
}
|
||||
}
|
||||
|
|
@ -39,6 +39,7 @@ internal class Get : ElsaEndpoint<Request, Response>
|
|||
{
|
||||
WorkflowInstanceId = request.WorkflowInstanceId,
|
||||
ActivityIds = request.Filter?.ActivityIds,
|
||||
ActivityNodeIds = request.Filter?.ActivityNodeIds,
|
||||
ExcludeActivityTypes = request.Filter?.ExcludedActivityTypes,
|
||||
EventNames = request.Filter?.EventNames,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -5,45 +5,32 @@ using FastEndpoints;
|
|||
|
||||
namespace Elsa.Workflows.Api.Endpoints.WorkflowInstances.Journal.FilteredList;
|
||||
|
||||
/// <summary>
|
||||
/// Represents a request for a page of workflow execution log records.
|
||||
/// </summary>
|
||||
internal class Request
|
||||
{
|
||||
/// <summary>
|
||||
/// The ID of the workflow instance to get the execution log for.
|
||||
/// </summary>
|
||||
[BindFrom("id")] public string WorkflowInstanceId { get; set; } = default!;
|
||||
|
||||
/// <summary>
|
||||
/// The filter to apply.
|
||||
/// </summary>
|
||||
public JournalFilter? Filter { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The zero-based page number to get.
|
||||
/// </summary>
|
||||
public int? Page { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The size of the page to get.
|
||||
/// </summary>
|
||||
public int? PageSize { get; set; }
|
||||
|
||||
/// <summary>
|
||||
|
||||
/// The number of records to skip.
|
||||
/// </summary>
|
||||
public int? Skip { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The number of records to take.
|
||||
/// </summary>
|
||||
public int? Take { get; set; }
|
||||
}
|
||||
|
||||
internal class JournalFilter
|
||||
{
|
||||
public ICollection<string>? ActivityIds { get; set; }
|
||||
public ICollection<string>? ActivityNodeIds { get; set; }
|
||||
public ICollection<string>? ExcludedActivityTypes { get; set; }
|
||||
public ICollection<string>? EventNames { get; set; }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@ public class StaticWorkflowDefinitionLinker(
|
|||
Outputs = workflowDefinitionModel.Outputs,
|
||||
Outcomes = workflowDefinitionModel.Outcomes,
|
||||
CustomProperties = workflowDefinitionModel.CustomProperties,
|
||||
PropertyBag = workflowDefinitionModel.PropertyBag,
|
||||
IsReadonly = workflowDefinitionModel.IsReadonly,
|
||||
IsSystem = workflowDefinitionModel.IsSystem,
|
||||
IsLatest = workflowDefinitionModel.IsLatest,
|
||||
|
|
@ -99,6 +100,7 @@ public class StaticWorkflowDefinitionLinker(
|
|||
Outputs = item.Outputs,
|
||||
Outcomes = item.Outcomes,
|
||||
CustomProperties = item.CustomProperties,
|
||||
PropertyBag = item.PropertyBag,
|
||||
IsReadonly = item.IsReadonly,
|
||||
IsSystem = item.IsSystem,
|
||||
IsLatest = item.IsLatest,
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
using System.ComponentModel;
|
||||
using Elsa.Common.Models;
|
||||
using Elsa.Expressions.Models;
|
||||
using Elsa.Workflows.Attributes;
|
||||
using Elsa.Workflows.Contracts;
|
||||
|
|
@ -30,6 +31,7 @@ public class Workflow : Composite<object>, ICloneable
|
|||
ICollection<OutputDefinition> outputs,
|
||||
ICollection<string> outcomes,
|
||||
IDictionary<string, object> customProperties,
|
||||
PropertyBag propertyBag,
|
||||
bool isReadonly,
|
||||
bool isSystem)
|
||||
{
|
||||
|
|
@ -38,6 +40,7 @@ public class Workflow : Composite<object>, ICloneable
|
|||
Inputs = inputs;
|
||||
Outputs = outputs;
|
||||
Outcomes = outcomes;
|
||||
PropertyBag = propertyBag;
|
||||
WorkflowMetadata = workflowMetadata;
|
||||
Options = options;
|
||||
Variables = variables;
|
||||
|
|
@ -96,6 +99,11 @@ public class Workflow : Composite<object>, ICloneable
|
|||
/// Gets or sets options for the workflow.
|
||||
/// </summary>
|
||||
public WorkflowOptions Options { get; set; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// A bag of properties that can be used by applications and modules to store information that can be shared with tooling.
|
||||
/// </summary>
|
||||
public PropertyBag PropertyBag { get; set; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// Make workflow definition readonly.
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
using Elsa.Common.Models;
|
||||
using Elsa.Extensions;
|
||||
using Elsa.Workflows.Activities;
|
||||
using Elsa.Workflows.Contracts;
|
||||
|
|
@ -7,25 +8,9 @@ using Elsa.Workflows.Models;
|
|||
namespace Elsa.Workflows.Builders;
|
||||
|
||||
/// <inheritdoc />
|
||||
public class WorkflowBuilder : IWorkflowBuilder
|
||||
public class WorkflowBuilder(IActivityVisitor activityVisitor, IIdentityGraphService identityGraphService, IActivityRegistry activityRegistry, IIdentityGenerator identityGenerator)
|
||||
: IWorkflowBuilder
|
||||
{
|
||||
private readonly IActivityVisitor _activityVisitor;
|
||||
private readonly IIdentityGraphService _identityGraphService;
|
||||
private readonly IActivityRegistry _activityRegistry;
|
||||
private readonly IIdentityGenerator _identityGenerator;
|
||||
|
||||
/// <summary>
|
||||
/// Constructor.
|
||||
/// </summary>
|
||||
public WorkflowBuilder(IActivityVisitor activityVisitor, IIdentityGraphService identityGraphService, IActivityRegistry activityRegistry, IIdentityGenerator identityGenerator)
|
||||
{
|
||||
_activityVisitor = activityVisitor;
|
||||
_identityGraphService = identityGraphService;
|
||||
_activityRegistry = activityRegistry;
|
||||
_identityGenerator = identityGenerator;
|
||||
Result = new Variable();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public string? Id { get; set; }
|
||||
|
||||
|
|
@ -66,11 +51,14 @@ public class WorkflowBuilder : IWorkflowBuilder
|
|||
public ICollection<string> Outcomes { get; set; } = new List<string>();
|
||||
|
||||
/// <inheritdoc />
|
||||
public Variable? Result { get; set; }
|
||||
public Variable? Result { get; set; } = new();
|
||||
|
||||
/// <inheritdoc />
|
||||
public IDictionary<string, object> CustomProperties { get; set; } = new Dictionary<string, object>();
|
||||
|
||||
/// <inheritdoc />
|
||||
public PropertyBag PropertyBag { get; set; } = new();
|
||||
|
||||
/// <inheritdoc />
|
||||
public WorkflowOptions WorkflowOptions { get; } = new();
|
||||
|
||||
|
|
@ -234,7 +222,7 @@ public class WorkflowBuilder : IWorkflowBuilder
|
|||
var publication = WorkflowPublication.LatestAndPublished;
|
||||
var name = string.IsNullOrEmpty(Name) ? definitionId : Name;
|
||||
var workflowMetadata = new WorkflowMetadata(name, Description);
|
||||
var workflow = new Workflow(identity, publication, workflowMetadata, WorkflowOptions, root, Variables, Inputs, Outputs, Outcomes, CustomProperties, IsReadonly, IsSystem);
|
||||
var workflow = new Workflow(identity, publication, workflowMetadata, WorkflowOptions, root, Variables, Inputs, Outputs, Outcomes, CustomProperties, PropertyBag, IsReadonly, IsSystem);
|
||||
|
||||
// If a Result variable is defined, install it into the workflow, so we can capture the output into it.
|
||||
if (Result != null)
|
||||
|
|
@ -243,15 +231,15 @@ public class WorkflowBuilder : IWorkflowBuilder
|
|||
workflow.Result = new Output<object>(Result);
|
||||
}
|
||||
|
||||
var graph = await _activityVisitor.VisitAsync(workflow, cancellationToken);
|
||||
var graph = await activityVisitor.VisitAsync(workflow, cancellationToken);
|
||||
var nodes = graph.Flatten().ToList();
|
||||
|
||||
// Register all activity types first. The identity graph service will need to know about all activity types.
|
||||
var distinctActivityTypes = nodes.Select(x => x.Activity.GetType()).Distinct().ToList();
|
||||
await _activityRegistry.RegisterAsync(distinctActivityTypes, cancellationToken);
|
||||
await activityRegistry.RegisterAsync(distinctActivityTypes, cancellationToken);
|
||||
|
||||
// Assign identities to all activities.
|
||||
await _identityGraphService.AssignIdentitiesAsync(nodes);
|
||||
await identityGraphService.AssignIdentitiesAsync(nodes);
|
||||
|
||||
// Give unnamed variables in each variable container a predictable name.
|
||||
var variableContainers = nodes.Where(x => x.Activity is IVariableContainer).Select(x => (IVariableContainer)x.Activity).ToList();
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
using Elsa.Common.Models;
|
||||
using Elsa.Workflows.Activities;
|
||||
using Elsa.Workflows.Memory;
|
||||
using Elsa.Workflows.Models;
|
||||
|
|
@ -87,8 +88,14 @@ public interface IWorkflowBuilder
|
|||
/// <summary>
|
||||
/// A set of properties that can be used for storing application-specific information about the workflow being built.
|
||||
/// </summary>
|
||||
[Obsolete("Use PropertyBag instead")]
|
||||
IDictionary<string, object> CustomProperties { get; }
|
||||
|
||||
/// <summary>
|
||||
/// A set of properties that can be used for storing application-specific information about the workflow being built.
|
||||
/// </summary>
|
||||
PropertyBag PropertyBag { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// A fluent method for setting the <see cref="DefinitionId"/> property.
|
||||
/// </summary>
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
using Elsa.Common.Entities;
|
||||
using Elsa.Common.Models;
|
||||
using Elsa.Workflows.Memory;
|
||||
using Elsa.Workflows.Models;
|
||||
|
||||
|
|
@ -54,11 +55,12 @@ public class WorkflowDefinition : VersionedEntity
|
|||
/// </summary>
|
||||
public ICollection<string> Outcomes { get; set; } = new List<string>();
|
||||
|
||||
/// <summary>
|
||||
/// Stores custom information about the workflow. Can be used to store application-specific properties to associate with the workflow.
|
||||
/// </summary>
|
||||
public IDictionary<string, object> CustomProperties { get; set; } = new Dictionary<string, object>();
|
||||
|
||||
/// Stores custom information about the workflow. Can be used to store application-specific properties to associate with the workflow.
|
||||
public PropertyBag PropertyBag { get; set; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// The name of the workflow provider that created this workflow, if any.
|
||||
/// </summary>
|
||||
|
|
@ -98,6 +100,5 @@ public class WorkflowDefinition : VersionedEntity
|
|||
/// <summary>
|
||||
/// Creates and returns a shallow copy of the workflow definition.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public WorkflowDefinition ShallowClone() => (WorkflowDefinition)MemberwiseClone();
|
||||
}
|
||||
|
|
@ -45,6 +45,7 @@ public class WorkflowDefinitionMapper
|
|||
source.Outputs,
|
||||
source.Outcomes,
|
||||
source.CustomProperties,
|
||||
source.PropertyBag,
|
||||
source.IsReadonly,
|
||||
source.IsSystem);
|
||||
}
|
||||
|
|
@ -77,6 +78,7 @@ public class WorkflowDefinitionMapper
|
|||
source.Outputs ?? new List<OutputDefinition>(),
|
||||
source.Outcomes ?? new List<string>(),
|
||||
source.CustomProperties ?? new Dictionary<string, object>(),
|
||||
source.PropertyBag ?? new(),
|
||||
source.IsReadonly,
|
||||
source.IsSystem);
|
||||
}
|
||||
|
|
@ -116,6 +118,7 @@ public class WorkflowDefinitionMapper
|
|||
workflowDefinition.Outputs,
|
||||
workflowDefinition.Outcomes,
|
||||
workflowDefinition.CustomProperties,
|
||||
workflowDefinition.PropertyBag,
|
||||
workflowDefinition.IsReadonly,
|
||||
workflowDefinition.IsSystem,
|
||||
workflowDefinition.IsLatest,
|
||||
|
|
@ -148,6 +151,7 @@ public class WorkflowDefinitionMapper
|
|||
workflow.Outputs,
|
||||
workflow.Outcomes,
|
||||
workflow.CustomProperties,
|
||||
workflow.PropertyBag,
|
||||
workflow.IsReadonly,
|
||||
workflow.IsSystem,
|
||||
workflow.Publication.IsLatest,
|
||||
|
|
|
|||
|
|
@ -1,12 +1,11 @@
|
|||
using Elsa.Common.Models;
|
||||
using Elsa.Workflows.Contracts;
|
||||
using Elsa.Workflows.Models;
|
||||
using JetBrains.Annotations;
|
||||
|
||||
namespace Elsa.Workflows.Management.Models;
|
||||
|
||||
/// <summary>
|
||||
/// Represents a serializable workflow definition.
|
||||
/// </summary>
|
||||
[PublicAPI]
|
||||
public record WorkflowDefinitionModel(
|
||||
string Id,
|
||||
|
|
@ -21,7 +20,9 @@ public record WorkflowDefinitionModel(
|
|||
ICollection<InputDefinition>? Inputs,
|
||||
ICollection<OutputDefinition>? Outputs,
|
||||
ICollection<string>? Outcomes,
|
||||
[property: Obsolete("Use PropertyBag instead")]
|
||||
IDictionary<string, object>? CustomProperties,
|
||||
PropertyBag? PropertyBag,
|
||||
bool IsReadonly,
|
||||
bool IsSystem,
|
||||
bool IsLatest,
|
||||
|
|
@ -45,7 +46,8 @@ public record WorkflowDefinitionModel(
|
|||
default!,
|
||||
default!,
|
||||
default!,
|
||||
default!,
|
||||
default,
|
||||
default,
|
||||
default!,
|
||||
default!,
|
||||
default!,
|
||||
|
|
|
|||
|
|
@ -95,7 +95,7 @@ public class WorkflowDefinitionManager : IWorkflowDefinitionManager
|
|||
{
|
||||
if (definitionToDelete.IsPublished)
|
||||
{
|
||||
throw new Exception("Published version cannot be deleted before retracting it");
|
||||
await _workflowPublisher.RetractAsync(definitionToDelete, cancellationToken);
|
||||
}
|
||||
|
||||
await _notificationSender.SendAsync(new WorkflowDefinitionVersionDeleting(definitionToDelete), cancellationToken);
|
||||
|
|
|
|||
|
|
@ -4,5 +4,5 @@
|
|||
"_island": "[\r\n {\r\n \u0022path\u0022: \u0022folder1\u0022,\r\n \u0022command\u0022: \u0022add\u0022\r\n }\r\n]",
|
||||
"_type": "Newtonsoft.Json.Linq.JArray, Newtonsoft.Json"
|
||||
},
|
||||
"_type": "ObjectDictionary"
|
||||
"_type": "ObjectMap"
|
||||
}
|
||||
|
|
@ -6,5 +6,5 @@
|
|||
"command": "add"
|
||||
}
|
||||
],
|
||||
"_type": "ObjectDictionary"
|
||||
"_type": "ObjectMap"
|
||||
}
|
||||
|
|
@ -4,5 +4,5 @@
|
|||
"_island": "{\r\n \u0022file1\u0022: {\r\n \u0022script\u0022: [\r\n {\r\n \u0022path\u0022: \u0022folder1\u0022,\r\n \u0022command\u0022: \u0022add\u0022\r\n }\r\n ]\r\n }\r\n}",
|
||||
"_type": "Newtonsoft.Json.Linq.JObject, Newtonsoft.Json"
|
||||
},
|
||||
"_type": "ObjectDictionary"
|
||||
"_type": "ObjectMap"
|
||||
}
|
||||
|
|
@ -10,5 +10,5 @@
|
|||
]
|
||||
}
|
||||
},
|
||||
"_type": "ObjectDictionary"
|
||||
"_type": "ObjectMap"
|
||||
}
|
||||
|
|
@ -4,5 +4,5 @@
|
|||
"_island": "[\r\n {\r\n \u0022path\u0022: \u0022folder1\u0022,\r\n \u0022command\u0022: \u0022add\u0022\r\n }\r\n]",
|
||||
"_type": "System.Text.Json.Nodes.JsonArray, System.Text.Json"
|
||||
},
|
||||
"_type": "ObjectDictionary"
|
||||
"_type": "ObjectMap"
|
||||
}
|
||||
|
|
@ -4,5 +4,5 @@
|
|||
"_island": "{\r\n \u0022file1\u0022: {\r\n \u0022script\u0022: [\r\n {\r\n \u0022path\u0022: \u0022folder1\u0022,\r\n \u0022command\u0022: \u0022add\u0022\r\n }\r\n ]\r\n }\r\n}",
|
||||
"_type": "System.Text.Json.Nodes.JsonObject, System.Text.Json"
|
||||
},
|
||||
"_type": "ObjectDictionary"
|
||||
"_type": "ObjectMap"
|
||||
}
|
||||
|
|
@ -10,5 +10,5 @@
|
|||
]
|
||||
}
|
||||
},
|
||||
"_type": "ObjectDictionary"
|
||||
"_type": "ObjectMap"
|
||||
}
|
||||
Loading…
Reference in a new issue