Refactored the IOutcomes to be completely data driven on the UI now.
This commit is contained in:
parent
88d6a1f136
commit
44ada3f332
@ -81,6 +81,9 @@ public class TaskMetadata
|
|||||||
public string TaskType { get; set; }
|
public string TaskType { get; set; }
|
||||||
public string DisplayName { get; set; }
|
public string DisplayName { get; set; }
|
||||||
public List<string> Capabilities { get; set; } = [];
|
public List<string> Capabilities { get; set; } = [];
|
||||||
|
|
||||||
|
public string OutcomeLabel { get; set; }
|
||||||
|
public List<string> Outcomes { get; set; } = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
public interface IWorkflowTemplateManager
|
public interface IWorkflowTemplateManager
|
||||||
|
|||||||
@ -143,7 +143,7 @@ public class WorkflowTemplateController : ESuiteControllerBase
|
|||||||
[ProducesResponseType(StatusCodes.Status400BadRequest, Type = typeof(ProblemDetails))]
|
[ProducesResponseType(StatusCodes.Status400BadRequest, Type = typeof(ProblemDetails))]
|
||||||
[AccessKey(SecurityAccess.DeleteWorkflowTemplate)]
|
[AccessKey(SecurityAccess.DeleteWorkflowTemplate)]
|
||||||
public async Task<IActionResult> DeleteWorkflowTemplateVersion(
|
public async Task<IActionResult> DeleteWorkflowTemplateVersion(
|
||||||
[FromBody] IGeneralIdRef templateId,
|
[FromBody] GeneralIdRef templateId,
|
||||||
CancellationToken cancellationToken = default!
|
CancellationToken cancellationToken = default!
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
using e_suite.API.Common;
|
using System.ComponentModel;
|
||||||
|
using e_suite.API.Common;
|
||||||
using e_suite.API.Common.exceptions;
|
using e_suite.API.Common.exceptions;
|
||||||
using e_suite.API.Common.repository;
|
using e_suite.API.Common.repository;
|
||||||
using e_suite.Database.Audit;
|
using e_suite.Database.Audit;
|
||||||
@ -251,6 +252,17 @@ public class WorkflowTemplateManager : IWorkflowTemplateManager
|
|||||||
};
|
};
|
||||||
newTaskMetadata.Capabilities.AddRange(capabilities);
|
newTaskMetadata.Capabilities.AddRange(capabilities);
|
||||||
|
|
||||||
|
var outcomeInterface = interfaces
|
||||||
|
.FirstOrDefault(i => i.IsGenericType &&
|
||||||
|
i.GetGenericTypeDefinition() == typeof(IOutcome<>));
|
||||||
|
var outcomeEnumType = outcomeInterface.GetGenericArguments()[0];
|
||||||
|
|
||||||
|
newTaskMetadata.OutcomeLabel = outcomeEnumType
|
||||||
|
.GetCustomAttribute<DescriptionAttribute>()?
|
||||||
|
.Description ?? outcomeEnumType.Name;
|
||||||
|
|
||||||
|
newTaskMetadata.Outcomes = Enum.GetNames(outcomeEnumType).Select( x => $"{outcomeEnumType.Name}.{x}").ToList();
|
||||||
|
|
||||||
return newTaskMetadata;
|
return newTaskMetadata;
|
||||||
})
|
})
|
||||||
.ToList();
|
.ToList();
|
||||||
|
|||||||
@ -4,7 +4,6 @@ using e_suite.Database.Core.Tables.Activity;
|
|||||||
using e_suite.Messaging.Common;
|
using e_suite.Messaging.Common;
|
||||||
using e_suite.Workflow.Core;
|
using e_suite.Workflow.Core;
|
||||||
using e_suite.Workflow.Core.Extensions;
|
using e_suite.Workflow.Core.Extensions;
|
||||||
using e_suite.Workflow.Core.Interfaces;
|
|
||||||
using eSuite.Core.Clock;
|
using eSuite.Core.Clock;
|
||||||
using eSuite.Core.Enums;
|
using eSuite.Core.Enums;
|
||||||
using eSuite.Core.Miscellaneous;
|
using eSuite.Core.Miscellaneous;
|
||||||
@ -60,7 +59,17 @@ public class WorkflowProcessor : IWorkflowProcessor
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var workflowVersion = _workflowConverter.DeserialiseFromDatabase(activityInstance.WorkflowVersion);
|
WorkflowVersion workflowVersion;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
workflowVersion = _workflowConverter.DeserialiseFromDatabase(activityInstance.WorkflowVersion);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
_logger.LogError("{DateTime}: Failed to Deserialise Json {messageId} - {messageId}", _clock.GetNow, activityId, e.ToString());
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
var hasCompletableTask = false;
|
var hasCompletableTask = false;
|
||||||
|
|
||||||
|
|||||||
@ -1,5 +1,8 @@
|
|||||||
namespace e_suite.Workflow.Core.Enums;
|
using System.ComponentModel;
|
||||||
|
|
||||||
|
namespace e_suite.Workflow.Core.Enums;
|
||||||
|
|
||||||
|
[Description("Verdict")]
|
||||||
public enum ApprovalVerdict
|
public enum ApprovalVerdict
|
||||||
{
|
{
|
||||||
None,
|
None,
|
||||||
|
|||||||
@ -1,5 +1,8 @@
|
|||||||
namespace e_suite.Workflow.Core.Enums;
|
using System.ComponentModel;
|
||||||
|
|
||||||
|
namespace e_suite.Workflow.Core.Enums;
|
||||||
|
|
||||||
|
[Description("Outcome")]
|
||||||
public enum DefaultOutcome
|
public enum DefaultOutcome
|
||||||
{
|
{
|
||||||
Complete
|
Complete
|
||||||
|
|||||||
@ -83,8 +83,15 @@ public static class TaskExtensions
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Deserialize JSON into the target type (handles lists, objects, primitives)
|
// Deserialize JSON into the target type (handles lists, objects, primitives)
|
||||||
|
try
|
||||||
|
{
|
||||||
value = JsonSerializer.Deserialize(je.GetRawText(), targetType, jsonSerializerOptions);
|
value = JsonSerializer.Deserialize(je.GetRawText(), targetType, jsonSerializerOptions);
|
||||||
}
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
prop.SetValue(obj, value);
|
prop.SetValue(obj, value);
|
||||||
@ -125,7 +132,7 @@ public static class TaskExtensions
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private (Type outcomeType, IDictionary dict)? GetOutcomeDictionary()
|
private (Type outcomeType, IEnumerable outcomeList)? GetOutcomeList()
|
||||||
{
|
{
|
||||||
var outcomeInterface = task.GetType()
|
var outcomeInterface = task.GetType()
|
||||||
.GetInterfaces()
|
.GetInterfaces()
|
||||||
@ -137,49 +144,45 @@ public static class TaskExtensions
|
|||||||
|
|
||||||
var outcomeType = outcomeInterface.GetGenericArguments()[0];
|
var outcomeType = outcomeInterface.GetGenericArguments()[0];
|
||||||
var prop = outcomeInterface.GetProperty("OutcomeActions");
|
var prop = outcomeInterface.GetProperty("OutcomeActions");
|
||||||
var dict = (IDictionary)prop!.GetValue(task)!;
|
|
||||||
|
|
||||||
return (outcomeType, dict);
|
var list = (IEnumerable)prop!.GetValue(task)!;
|
||||||
|
|
||||||
|
return (outcomeType, list);
|
||||||
}
|
}
|
||||||
|
|
||||||
public IEnumerable<Guid> GetTargetGuids()
|
public IEnumerable<Guid> GetTargetGuids()
|
||||||
{
|
{
|
||||||
var info = task.GetOutcomeDictionary();
|
var info = task.GetOutcomeList();
|
||||||
if (info == null)
|
if (info == null)
|
||||||
return Enumerable.Empty<Guid>();
|
yield break;
|
||||||
|
|
||||||
return info.Value.dict.Values.Cast<Guid>();
|
foreach (var item in info.Value.outcomeList.Cast<IOutcomeAction>())
|
||||||
|
yield return item.Task;
|
||||||
}
|
}
|
||||||
|
|
||||||
public IEnumerable<Guid> GetTargetGuids(IEnumerable<string> outcomes)
|
public IEnumerable<Guid> GetTargetGuids(IEnumerable<string> outcomes)
|
||||||
{
|
{
|
||||||
var info = task.GetOutcomeDictionary();
|
var info = task.GetOutcomeList();
|
||||||
if (info == null)
|
if (info == null)
|
||||||
return Enumerable.Empty<Guid>();
|
return Enumerable.Empty<Guid>();
|
||||||
|
|
||||||
var (outcomeType, dict) = info.Value;
|
var (outcomeType, list) = info.Value;
|
||||||
var results = new List<Guid>();
|
|
||||||
|
|
||||||
foreach (var outcomeString in outcomes)
|
var typedOutcomes = outcomes.Select(o =>
|
||||||
{
|
outcomeType.IsEnum
|
||||||
object? typedKey;
|
? Enum.Parse(outcomeType, o, true)
|
||||||
|
: Convert.ChangeType(o, outcomeType)
|
||||||
|
).ToHashSet();
|
||||||
|
|
||||||
if (outcomeType.IsEnum)
|
return list
|
||||||
|
.Cast<object>()
|
||||||
|
.Where(item =>
|
||||||
{
|
{
|
||||||
typedKey = Enum.Parse(outcomeType, outcomeString);
|
var outcomeProp = item.GetType().GetProperty("Outcome");
|
||||||
}
|
var outcomeValue = outcomeProp!.GetValue(item);
|
||||||
else
|
return typedOutcomes.Contains(outcomeValue);
|
||||||
{
|
})
|
||||||
typedKey = Convert.ChangeType(outcomeString, outcomeType);
|
.Select(item => ((IOutcomeAction)item).Task);
|
||||||
}
|
|
||||||
|
|
||||||
if (dict.Contains(typedKey))
|
|
||||||
{
|
|
||||||
results.Add((Guid)dict[typedKey]!);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return results;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task StartTask(ActivityTask activityTask, IClock clock)
|
public async Task StartTask(ActivityTask activityTask, IClock clock)
|
||||||
|
|||||||
@ -2,11 +2,22 @@
|
|||||||
|
|
||||||
namespace e_suite.Workflow.Core.Interfaces;
|
namespace e_suite.Workflow.Core.Interfaces;
|
||||||
|
|
||||||
|
public interface IOutcomeAction
|
||||||
|
{
|
||||||
|
Guid Task { get; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class OutcomeAction<T> : IOutcomeAction
|
||||||
|
{
|
||||||
|
public T Outcome { get; set; }
|
||||||
|
public Guid Task { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
[TaskCapability]
|
[TaskCapability]
|
||||||
public interface IOutcome<T>
|
public interface IOutcome<T>
|
||||||
{
|
{
|
||||||
//Todo runtime only property.
|
//Todo runtime only property.
|
||||||
//public T? TaskOutcome { get; set; }
|
//public T? TaskOutcome { get; set; }
|
||||||
|
|
||||||
Dictionary<T, Guid> OutcomeActions { get; set; }
|
List<OutcomeAction<T>> OutcomeActions { get; set; }
|
||||||
}
|
}
|
||||||
@ -9,6 +9,5 @@ public class AdhocApprovalTask : TaskBase, IAssignees<ApprovalTaskAssignee>, IOu
|
|||||||
{
|
{
|
||||||
public List<ApprovalTaskAssignee> Assignees { get; set; } = [];
|
public List<ApprovalTaskAssignee> Assignees { get; set; } = [];
|
||||||
public ApprovalVerdict TaskOutcome { get; set; }
|
public ApprovalVerdict TaskOutcome { get; set; }
|
||||||
public Dictionary<ApprovalVerdict, Guid> OutcomeActions { get; set; } = [];
|
public List<OutcomeAction<ApprovalVerdict>> OutcomeActions { get; set; } = [];
|
||||||
public bool OverrideDefaultTaskProgression { get; set; }
|
|
||||||
}
|
}
|
||||||
@ -9,5 +9,6 @@ public class ApprovalStep : TaskBase, IAssignees<ApprovalTaskAssignee>, IOutcome
|
|||||||
{
|
{
|
||||||
public List<ApprovalTaskAssignee> Assignees { get; set; } = [];
|
public List<ApprovalTaskAssignee> Assignees { get; set; } = [];
|
||||||
|
|
||||||
public Dictionary<DefaultOutcome, Guid> OutcomeActions { get; set; } = [];
|
|
||||||
|
public List<OutcomeAction<DefaultOutcome>> OutcomeActions { get; set; } = [];
|
||||||
}
|
}
|
||||||
@ -9,6 +9,6 @@ public class ApprovalTask : TaskBase, IStage<ApprovalTaskAttribute>, IOutcome<Ap
|
|||||||
{
|
{
|
||||||
public ICollection<ITask> Tasks { get; } = new List<ITask>();
|
public ICollection<ITask> Tasks { get; } = new List<ITask>();
|
||||||
public ApprovalVerdict TaskOutcome { get; set; }
|
public ApprovalVerdict TaskOutcome { get; set; }
|
||||||
public Dictionary<ApprovalVerdict, Guid> OutcomeActions { get; set; } = [];
|
|
||||||
public bool OverrideDefaultTaskProgression { get; set; }
|
public List<OutcomeAction<ApprovalVerdict>> OutcomeActions { get; set; } = [];
|
||||||
}
|
}
|
||||||
@ -7,5 +7,5 @@ namespace e_suite.Workflow.Core.Tasks;
|
|||||||
[GeneralTask]
|
[GeneralTask]
|
||||||
public class AssetUploadTask : TaskBase, IOutcome<DefaultOutcome>
|
public class AssetUploadTask : TaskBase, IOutcome<DefaultOutcome>
|
||||||
{
|
{
|
||||||
public Dictionary<DefaultOutcome, Guid> OutcomeActions { get; set; } = [];
|
public List<OutcomeAction<DefaultOutcome>> OutcomeActions { get; set; } = [];
|
||||||
}
|
}
|
||||||
@ -12,5 +12,6 @@ namespace e_suite.Workflow.Core.Tasks;
|
|||||||
public class BasicTask : TaskBase, IAssignees<TaskAssignee>, IOutcome<DefaultOutcome>
|
public class BasicTask : TaskBase, IAssignees<TaskAssignee>, IOutcome<DefaultOutcome>
|
||||||
{
|
{
|
||||||
public List<TaskAssignee> Assignees { get; set; } = [];
|
public List<TaskAssignee> Assignees { get; set; } = [];
|
||||||
public Dictionary<DefaultOutcome, Guid> OutcomeActions { get; set; } = [];
|
|
||||||
|
public List<OutcomeAction<DefaultOutcome>> OutcomeActions { get; set; } = [];
|
||||||
}
|
}
|
||||||
@ -11,5 +11,6 @@ namespace e_suite.Workflow.Core.Tasks;
|
|||||||
public class ContentCollationTask : TaskBase, IAssignees<TaskAssignee>, IOutcome<DefaultOutcome>
|
public class ContentCollationTask : TaskBase, IAssignees<TaskAssignee>, IOutcome<DefaultOutcome>
|
||||||
{
|
{
|
||||||
public List<TaskAssignee> Assignees { get; set; } = [];
|
public List<TaskAssignee> Assignees { get; set; } = [];
|
||||||
public Dictionary<DefaultOutcome, Guid> OutcomeActions { get; set; } = [];
|
|
||||||
|
public List<OutcomeAction<DefaultOutcome>> OutcomeActions { get; set; } = [];
|
||||||
}
|
}
|
||||||
@ -10,5 +10,5 @@ namespace e_suite.Workflow.Core.Tasks;
|
|||||||
[GeneralTask(allowMultiple: false)]
|
[GeneralTask(allowMultiple: false)]
|
||||||
public class FileReleaseTask : TaskBase, IOutcome<DefaultOutcome>
|
public class FileReleaseTask : TaskBase, IOutcome<DefaultOutcome>
|
||||||
{
|
{
|
||||||
public Dictionary<DefaultOutcome, Guid> OutcomeActions { get; set; } = [];
|
public List<OutcomeAction<DefaultOutcome>> OutcomeActions { get; set; } = [];
|
||||||
}
|
}
|
||||||
@ -17,6 +17,5 @@ public class FormDataInputTask : TaskBase, IAssignees<TaskAssignee>, IFormTempla
|
|||||||
if (FormIdRef == null)
|
if (FormIdRef == null)
|
||||||
yield return "FormIdRef is required.";
|
yield return "FormIdRef is required.";
|
||||||
}
|
}
|
||||||
|
public List<OutcomeAction<DefaultOutcome>> OutcomeActions { get; set; } = [];
|
||||||
public Dictionary<DefaultOutcome, Guid> OutcomeActions { get; set; } = [];
|
|
||||||
}
|
}
|
||||||
@ -7,5 +7,5 @@ namespace e_suite.Workflow.Core.Tasks;
|
|||||||
[GeneralTask]
|
[GeneralTask]
|
||||||
public class LinkActivityTask : TaskBase, IOutcome<DefaultOutcome>
|
public class LinkActivityTask : TaskBase, IOutcome<DefaultOutcome>
|
||||||
{
|
{
|
||||||
public Dictionary<DefaultOutcome, Guid> OutcomeActions { get; set; } = [];
|
public List<OutcomeAction<DefaultOutcome>> OutcomeActions { get; set; } = [];
|
||||||
}
|
}
|
||||||
@ -13,7 +13,7 @@ namespace e_suite.Workflow.Core.Tasks;
|
|||||||
[GeneralTask]
|
[GeneralTask]
|
||||||
public class MilestoneTask : TaskBase, IOutcome<DefaultOutcome>
|
public class MilestoneTask : TaskBase, IOutcome<DefaultOutcome>
|
||||||
{
|
{
|
||||||
public Dictionary<DefaultOutcome, Guid> OutcomeActions { get; set; } = [];
|
public List<OutcomeAction<DefaultOutcome>> OutcomeActions { get; set; } = [];
|
||||||
|
|
||||||
public override async Task OnStartedAsync(ActivityTask activityTask)
|
public override async Task OnStartedAsync(ActivityTask activityTask)
|
||||||
{
|
{
|
||||||
@ -21,4 +21,6 @@ public class MilestoneTask : TaskBase, IOutcome<DefaultOutcome>
|
|||||||
activityTask.AddOutcome(DefaultOutcome.Complete);
|
activityTask.AddOutcome(DefaultOutcome.Complete);
|
||||||
activityTask.SetState(ActivityState.ReadyToComplete);
|
activityTask.SetState(ActivityState.ReadyToComplete);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -10,5 +10,6 @@ public class StageTask : TaskBase, IStage<GeneralTaskAttribute>, IBypassable, IO
|
|||||||
public ICollection<ITask> Tasks { get; } = new List<ITask>();
|
public ICollection<ITask> Tasks { get; } = new List<ITask>();
|
||||||
|
|
||||||
public bool Bypassable { get; set; }
|
public bool Bypassable { get; set; }
|
||||||
public Dictionary<DefaultOutcome, Guid> OutcomeActions { get; set; } = [];
|
|
||||||
|
public List<OutcomeAction<DefaultOutcome>> OutcomeActions { get; set; } = [];
|
||||||
}
|
}
|
||||||
@ -7,5 +7,5 @@ namespace e_suite.Workflow.Core.Tasks;
|
|||||||
[GeneralTask]
|
[GeneralTask]
|
||||||
public class VisualBriefReviewTask : TaskBase, IOutcome<DefaultOutcome>
|
public class VisualBriefReviewTask : TaskBase, IOutcome<DefaultOutcome>
|
||||||
{
|
{
|
||||||
public Dictionary<DefaultOutcome, Guid> OutcomeActions { get; set; } = [];
|
public List<OutcomeAction<DefaultOutcome>> OutcomeActions { get; set; } = [];
|
||||||
}
|
}
|
||||||
@ -7,5 +7,5 @@ namespace e_suite.Workflow.Core.Tasks;
|
|||||||
[GeneralTask]
|
[GeneralTask]
|
||||||
public class VisualBriefUploadTask : TaskBase, IOutcome<DefaultOutcome>
|
public class VisualBriefUploadTask : TaskBase, IOutcome<DefaultOutcome>
|
||||||
{
|
{
|
||||||
public Dictionary<DefaultOutcome, Guid> OutcomeActions { get; set; } = [];
|
public List<OutcomeAction<DefaultOutcome>> OutcomeActions { get; set; } = [];
|
||||||
}
|
}
|
||||||
Loading…
Reference in New Issue
Block a user