Work towards implementing a workflow template editor
This commit is contained in:
parent
17aea93370
commit
af02ede4e3
29
e-suite.API.Common/e-suite.API.Common/GetWorkflowTemplate.cs
Normal file
29
e-suite.API.Common/e-suite.API.Common/GetWorkflowTemplate.cs
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
using e_suite.Database.Core.Models;
|
||||||
|
using e_suite.Database.Core.Tables.Workflow;
|
||||||
|
|
||||||
|
namespace e_suite.API.Common;
|
||||||
|
|
||||||
|
public class GetWorkflowTemplate : IGeneralId
|
||||||
|
{
|
||||||
|
public GetWorkflowTemplate( Workflow workflow)
|
||||||
|
{
|
||||||
|
Id = workflow.Id;
|
||||||
|
Guid = workflow.Guid;
|
||||||
|
WorkflowName = workflow.Name;
|
||||||
|
Version = workflow.Versions.Max(x => x.Version);
|
||||||
|
Deleted = workflow.Deleted;
|
||||||
|
LastUpdated = workflow.LastUpdated;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long Version { get; set; }
|
||||||
|
|
||||||
|
public DateTimeOffset LastUpdated { get; set; }
|
||||||
|
|
||||||
|
public bool Deleted { get; set; }
|
||||||
|
|
||||||
|
public string WorkflowName { get; set; }
|
||||||
|
|
||||||
|
public Guid Guid { get; set; }
|
||||||
|
|
||||||
|
public long Id { get; set; }
|
||||||
|
}
|
||||||
@ -7,43 +7,43 @@ using eSuite.Core.Miscellaneous;
|
|||||||
|
|
||||||
namespace e_suite.API.Common;
|
namespace e_suite.API.Common;
|
||||||
|
|
||||||
public class GetWorkflowTemplate : IGeneralId
|
public class GetWorkflowTemplateVersion : IGeneralId
|
||||||
{
|
{
|
||||||
public GetWorkflowTemplate()
|
public GetWorkflowTemplateVersion()
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public GetWorkflowTemplate(WorkflowVersion workflowVersion)
|
public GetWorkflowTemplateVersion(WorkflowVersion workflowVersion)
|
||||||
{
|
{
|
||||||
Id = workflowVersion.Id;
|
Id = workflowVersion.Id;
|
||||||
Guid = workflowVersion.Guid;
|
Guid = workflowVersion.Guid;
|
||||||
Deleted = workflowVersion.Deleted;
|
Deleted = workflowVersion.Deleted;
|
||||||
ActivityNameTemplate = workflowVersion.ActivityNameTemplate;
|
ActivityNameTemplate = workflowVersion.ActivityNameTemplate;
|
||||||
Description = workflowVersion.Description;
|
Description = workflowVersion.Description;
|
||||||
DomainId = workflowVersion.Domain.ToGeneralIdRef();
|
DomainId = workflowVersion.Domain.ToGeneralIdRef()!;
|
||||||
LastUpdated = workflowVersion.LastUpdated;
|
LastUpdated = workflowVersion.LastUpdated;
|
||||||
Version = workflowVersion.Version;
|
Version = workflowVersion.Version;
|
||||||
WorkflowId = workflowVersion.Workflow.ToGeneralIdRef();
|
WorkflowId = workflowVersion.Workflow.ToGeneralIdRef()!;
|
||||||
WorkflowName = workflowVersion.Workflow.Name;
|
WorkflowName = workflowVersion.Workflow.Name;
|
||||||
Tasks = workflowVersion.Tasks;
|
Tasks = workflowVersion.Tasks;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<TaskDefinition> Tasks { get; set; }
|
public List<TaskDefinition> Tasks { get; set; } = [];
|
||||||
|
|
||||||
public string WorkflowName { get; set; }
|
public string WorkflowName { get; set; } = string.Empty;
|
||||||
|
|
||||||
public GeneralIdRef? WorkflowId { get; set; }
|
public GeneralIdRef WorkflowId { get; set; } = null!;
|
||||||
|
|
||||||
public long Version { get; set; }
|
public long Version { get; set; }
|
||||||
|
|
||||||
public DateTimeOffset LastUpdated { get; set; }
|
public DateTimeOffset LastUpdated { get; set; }
|
||||||
|
|
||||||
public GeneralIdRef? DomainId { get; set; }
|
public GeneralIdRef DomainId { get; set; } = null!;
|
||||||
|
|
||||||
public string Description { get; set; }
|
public string Description { get; set; } = string.Empty;
|
||||||
|
|
||||||
public string ActivityNameTemplate { get; set; }
|
public string ActivityNameTemplate { get; set; } = string.Empty;
|
||||||
|
|
||||||
public bool Deleted { get; set; }
|
public bool Deleted { get; set; }
|
||||||
|
|
||||||
@ -51,25 +51,23 @@ public class GetWorkflowTemplate : IGeneralId
|
|||||||
public Guid Guid { get; set; }
|
public Guid Guid { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class EditWorkflowTemplate : IGeneralId
|
public class EditWorkflowTemplateVersion : IGeneralId
|
||||||
{
|
{
|
||||||
public long Id { get; set; }
|
public long Id { get; set; }
|
||||||
public Guid Guid { get; set; }
|
public Guid Guid { get; set; }
|
||||||
|
|
||||||
public string WorkflowName { get; set; }
|
|
||||||
|
|
||||||
public GeneralIdRef? WorkflowId { get; set; }
|
|
||||||
|
|
||||||
public long Version { get; set; }
|
public long Version { get; set; }
|
||||||
|
|
||||||
public GeneralIdRef? DomainId { get; set; }
|
public GeneralIdRef? DomainId { get; set; }
|
||||||
|
|
||||||
public string Description { get; set; }
|
public string Description { get; set; } = String.Empty;
|
||||||
|
|
||||||
public string ActivityNameTemplate { get; set; }
|
public string ActivityNameTemplate { get; set; } = String.Empty;
|
||||||
|
|
||||||
|
public List<TaskDefinition> Tasks { get; set; } = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
public class PatchWorkflowTemplate
|
public class PatchWorkflowTemplateVersion
|
||||||
{
|
{
|
||||||
|
|
||||||
public string? WorkflowName { get; set; }
|
public string? WorkflowName { get; set; }
|
||||||
@ -81,33 +79,29 @@ public class PatchWorkflowTemplate
|
|||||||
public string? ActivityNameTemplate { get; set; }
|
public string? ActivityNameTemplate { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class CreateWorkflowTemplate
|
public class CreateWorkflowTemplateVersion
|
||||||
{
|
{
|
||||||
public List<TaskDefinition> Tasks { get; set; }
|
public List<TaskDefinition> Tasks { get; set; } = [];
|
||||||
|
|
||||||
public string WorkflowName { get; set; }
|
public required GeneralIdRef WorkflowId { get; set; }
|
||||||
|
|
||||||
public GeneralIdRef? WorkflowId { get; set; }
|
|
||||||
|
|
||||||
public long Version { get; set; }
|
public long Version { get; set; }
|
||||||
|
|
||||||
public DateTimeOffset LastUpdated { get; set; }
|
public required GeneralIdRef DomainId { get; set; }
|
||||||
|
|
||||||
public GeneralIdRef? DomainId { get; set; }
|
public string Description { get; set; } = String.Empty;
|
||||||
|
|
||||||
public string Description { get; set; }
|
public string ActivityNameTemplate { get; set; } = String.Empty;
|
||||||
|
|
||||||
public string ActivityNameTemplate { get; set; }
|
|
||||||
|
|
||||||
public bool Deleted { get; set; }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public interface IWorkflowTemplateManager
|
public interface IWorkflowTemplateManager
|
||||||
{
|
{
|
||||||
Task<PaginatedData<GetWorkflowTemplate>> GetWorkflowTemplatesAsync(Paging paging, CancellationToken cancellationToken);
|
Task<PaginatedData<GetWorkflowTemplate>> GetWorkflowTemplatesAsync(Paging paging, CancellationToken cancellationToken);
|
||||||
Task<GetWorkflowTemplate?> GetWorkflowTemplateAsync(GeneralIdRef generalIdRef, CancellationToken cancellationToken);
|
|
||||||
Task EditTemplate(AuditUserDetails auditUserDetails, EditWorkflowTemplate template, CancellationToken cancellationToken);
|
Task<PaginatedData<GetWorkflowTemplateVersion>> GetWorkflowTemplateVersionsAsync(Paging paging, CancellationToken cancellationToken);
|
||||||
Task PatchTemplate(AuditUserDetails auditUserDetails, IGeneralIdRef templateId, PatchWorkflowTemplate patchTemplate, CancellationToken cancellationToken);
|
Task<GetWorkflowTemplateVersion?> GetWorkflowTemplateVersionAsync(GeneralIdRef generalIdRef, CancellationToken cancellationToken);
|
||||||
Task PostTemplate(AuditUserDetails auditUserDetails, CreateWorkflowTemplate template, CancellationToken cancellationToken);
|
Task EditTemplateVersion(AuditUserDetails auditUserDetails, EditWorkflowTemplateVersion template, CancellationToken cancellationToken);
|
||||||
Task DeleteTemplate(AuditUserDetails auditUserDetails, IGeneralIdRef templateId, CancellationToken cancellationToken);
|
Task PatchTemplateVersion(AuditUserDetails auditUserDetails, IGeneralIdRef templateId, PatchWorkflowTemplateVersion patchTemplate, CancellationToken cancellationToken);
|
||||||
|
Task PostTemplateVersion(AuditUserDetails auditUserDetails, CreateWorkflowTemplateVersion template, CancellationToken cancellationToken);
|
||||||
|
Task DeleteTemplateVersion(AuditUserDetails auditUserDetails, IGeneralIdRef templateId, CancellationToken cancellationToken);
|
||||||
}
|
}
|
||||||
@ -6,6 +6,7 @@ namespace e_suite.API.Common.repository;
|
|||||||
|
|
||||||
public interface IWorkflowTemplateRepository : IRepository
|
public interface IWorkflowTemplateRepository : IRepository
|
||||||
{
|
{
|
||||||
|
public IQueryable<Workflow> GetWorkflows();
|
||||||
IQueryable<WorkflowVersion> GetWorkflowVersions();
|
IQueryable<WorkflowVersion> GetWorkflowVersions();
|
||||||
Task EditWorkflowVersionAsync(AuditUserDetails auditUserDetails, WorkflowVersion workflowVersion, CancellationToken cancellationToken);
|
Task EditWorkflowVersionAsync(AuditUserDetails auditUserDetails, WorkflowVersion workflowVersion, CancellationToken cancellationToken);
|
||||||
}
|
}
|
||||||
@ -27,6 +27,7 @@ public class WorkflowTemplateController : ESuiteControllerBase
|
|||||||
_workflowTemplateManager = workflowTemplateManager;
|
_workflowTemplateManager = workflowTemplateManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Get a list of workflow templates
|
/// Get a list of workflow templates
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -37,30 +38,46 @@ public class WorkflowTemplateController : ESuiteControllerBase
|
|||||||
[Route("templates")]
|
[Route("templates")]
|
||||||
[AccessKey(SecurityAccess.ViewWorkflowTemplates)]
|
[AccessKey(SecurityAccess.ViewWorkflowTemplates)]
|
||||||
[HttpGet]
|
[HttpGet]
|
||||||
public async Task<IActionResult> GetWorkflowTemplates([FromQuery] Paging paging,CancellationToken cancellationToken = default!)
|
public async Task<IActionResult> GetWorkflowTemplates([FromQuery] Paging paging, CancellationToken cancellationToken = default!)
|
||||||
{
|
{
|
||||||
var result = await _workflowTemplateManager.GetWorkflowTemplatesAsync(paging, cancellationToken);
|
var result = await _workflowTemplateManager.GetWorkflowTemplatesAsync(paging, cancellationToken);
|
||||||
return Ok(result);
|
return Ok(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Get a list of workflow templates
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="paging"></param>
|
||||||
|
/// <param name="cancellationToken"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
/// <exception cref="NotImplementedException"></exception>
|
||||||
|
[Route("templateVersions")]
|
||||||
|
[AccessKey(SecurityAccess.ViewWorkflowTemplates)]
|
||||||
|
[HttpGet]
|
||||||
|
public async Task<IActionResult> GetWorkflowTemplateVersions([FromQuery] Paging paging,CancellationToken cancellationToken = default!)
|
||||||
|
{
|
||||||
|
var result = await _workflowTemplateManager.GetWorkflowTemplateVersionsAsync(paging, cancellationToken);
|
||||||
|
return Ok(result);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Get the details of specific template
|
/// Get the details of specific template
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="generalIdRef"></param>
|
/// <param name="generalIdRef"></param>
|
||||||
/// <param name="cancellationToken"></param>
|
/// <param name="cancellationToken"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
[Route("template")]
|
[Route("templateVersion")]
|
||||||
[HttpGet]
|
[HttpGet]
|
||||||
[AccessKey(SecurityAccess.ViewWorkflowTemplates)]
|
[AccessKey(SecurityAccess.ViewWorkflowTemplates)]
|
||||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||||
[ProducesResponseType(StatusCodes.Status400BadRequest)]
|
[ProducesResponseType(StatusCodes.Status400BadRequest)]
|
||||||
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
||||||
public async Task<IActionResult> GetWorkflowTemplate(
|
public async Task<IActionResult> GetWorkflowTemplateVersion(
|
||||||
[FromQuery] GeneralIdRef generalIdRef,
|
[FromQuery] GeneralIdRef generalIdRef,
|
||||||
CancellationToken cancellationToken = default!
|
CancellationToken cancellationToken = default!
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
var result = await _workflowTemplateManager.GetWorkflowTemplateAsync(generalIdRef, cancellationToken);
|
var result = await _workflowTemplateManager.GetWorkflowTemplateVersionAsync(generalIdRef, cancellationToken);
|
||||||
return Ok(result);
|
return Ok(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -70,14 +87,14 @@ public class WorkflowTemplateController : ESuiteControllerBase
|
|||||||
/// <param name="user"></param>
|
/// <param name="user"></param>
|
||||||
/// <param name="cancellationToken"></param>
|
/// <param name="cancellationToken"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
[Route("template")]
|
[Route("templateVersion")]
|
||||||
[HttpPut]
|
[HttpPut]
|
||||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||||
[ProducesResponseType(StatusCodes.Status400BadRequest)]
|
[ProducesResponseType(StatusCodes.Status400BadRequest)]
|
||||||
[AccessKey(SecurityAccess.EditWorkflowTemplate)]
|
[AccessKey(SecurityAccess.EditWorkflowTemplate)]
|
||||||
public async Task<IActionResult> EditTemplate(EditWorkflowTemplate template, CancellationToken cancellationToken = default!)
|
public async Task<IActionResult> EditTemplateVersion(EditWorkflowTemplateVersion template, CancellationToken cancellationToken = default!)
|
||||||
{
|
{
|
||||||
await _workflowTemplateManager.EditTemplate(AuditUserDetails, template, cancellationToken);
|
await _workflowTemplateManager.EditTemplateVersion(AuditUserDetails, template, cancellationToken);
|
||||||
return Ok();
|
return Ok();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -87,14 +104,14 @@ public class WorkflowTemplateController : ESuiteControllerBase
|
|||||||
/// <param name="user"></param>
|
/// <param name="user"></param>
|
||||||
/// <param name="cancellationToken"></param>
|
/// <param name="cancellationToken"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
[Route("template")]
|
[Route("templateVersion")]
|
||||||
[HttpPatch]
|
[HttpPatch]
|
||||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||||
[ProducesResponseType(StatusCodes.Status400BadRequest)]
|
[ProducesResponseType(StatusCodes.Status400BadRequest)]
|
||||||
[AccessKey(SecurityAccess.EditWorkflowTemplate)]
|
[AccessKey(SecurityAccess.EditWorkflowTemplate)]
|
||||||
public async Task<IActionResult> PatchWorkflowTemplate([FromQuery] IGeneralIdRef templateId, [FromBody] PatchWorkflowTemplate patchTemplate, CancellationToken cancellationToken = default!)
|
public async Task<IActionResult> PatchWorkflowTemplateVersion([FromQuery] IGeneralIdRef templateId, [FromBody] PatchWorkflowTemplateVersion patchTemplate, CancellationToken cancellationToken = default!)
|
||||||
{
|
{
|
||||||
await _workflowTemplateManager.PatchTemplate(AuditUserDetails, templateId, patchTemplate, cancellationToken);
|
await _workflowTemplateManager.PatchTemplateVersion(AuditUserDetails, templateId, patchTemplate, cancellationToken);
|
||||||
return Ok();
|
return Ok();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -105,17 +122,17 @@ public class WorkflowTemplateController : ESuiteControllerBase
|
|||||||
/// <param name="userRegistration">Contains the details that need to be supplied to create the user.</param>
|
/// <param name="userRegistration">Contains the details that need to be supplied to create the user.</param>
|
||||||
/// <param name="cancellationToken"></param>
|
/// <param name="cancellationToken"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
[Route("template")]
|
[Route("templateVersion")]
|
||||||
[HttpPost]
|
[HttpPost]
|
||||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||||
[ProducesResponseType(StatusCodes.Status400BadRequest, Type = typeof(ProblemDetails))]
|
[ProducesResponseType(StatusCodes.Status400BadRequest, Type = typeof(ProblemDetails))]
|
||||||
[AccessKey(SecurityAccess.AddWorkflowTemplate)]
|
[AccessKey(SecurityAccess.AddWorkflowTemplate)]
|
||||||
public async Task<IActionResult> CreateWorkflowTemplate(
|
public async Task<IActionResult> CreateWorkflowTemplateVersion(
|
||||||
[FromBody] CreateWorkflowTemplate template,
|
[FromBody] CreateWorkflowTemplateVersion template,
|
||||||
CancellationToken cancellationToken = default!
|
CancellationToken cancellationToken = default!
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
await _workflowTemplateManager.PostTemplate(AuditUserDetails, template, cancellationToken);
|
await _workflowTemplateManager.PostTemplateVersion(AuditUserDetails, template, cancellationToken);
|
||||||
return Ok();
|
return Ok();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -124,18 +141,18 @@ public class WorkflowTemplateController : ESuiteControllerBase
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="email"></param>
|
/// <param name="email"></param>
|
||||||
/// <param name="cancellationToken"></param>
|
/// <param name="cancellationToken"></param>
|
||||||
[Route("template")]
|
[Route("templateVersion")]
|
||||||
[HttpDelete]
|
[HttpDelete]
|
||||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||||
[ProducesResponseType(StatusCodes.Status404NotFound, Type = typeof(ProblemDetails))]
|
[ProducesResponseType(StatusCodes.Status404NotFound, Type = typeof(ProblemDetails))]
|
||||||
[ProducesResponseType(StatusCodes.Status400BadRequest, Type = typeof(ProblemDetails))]
|
[ProducesResponseType(StatusCodes.Status400BadRequest, Type = typeof(ProblemDetails))]
|
||||||
[AccessKey(SecurityAccess.DeleteWorkflowTemplate)]
|
[AccessKey(SecurityAccess.DeleteWorkflowTemplate)]
|
||||||
public async Task<IActionResult> DeleteWorkflowTemplate(
|
public async Task<IActionResult> DeleteWorkflowTemplateVersion(
|
||||||
[FromBody] IGeneralIdRef templateId,
|
[FromBody] IGeneralIdRef templateId,
|
||||||
CancellationToken cancellationToken = default!
|
CancellationToken cancellationToken = default!
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
await _workflowTemplateManager.DeleteTemplate(AuditUserDetails, templateId, cancellationToken);
|
await _workflowTemplateManager.DeleteTemplateVersion(AuditUserDetails, templateId, cancellationToken);
|
||||||
return Ok();
|
return Ok();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -60,6 +60,7 @@
|
|||||||
<ProjectReference Include="..\..\e-suite.Modules.SpecificationManager\e-suite.Modules.SpecificationManager\e-suite.Modules.SpecificationManager.csproj" />
|
<ProjectReference Include="..\..\e-suite.Modules.SpecificationManager\e-suite.Modules.SpecificationManager\e-suite.Modules.SpecificationManager.csproj" />
|
||||||
<ProjectReference Include="..\..\e-suite.Modules.SSOManager\e-suite.Modules.SSOManager\e-suite.Modules.SSOManager.csproj" />
|
<ProjectReference Include="..\..\e-suite.Modules.SSOManager\e-suite.Modules.SSOManager\e-suite.Modules.SSOManager.csproj" />
|
||||||
<ProjectReference Include="..\..\e-suite.Modules.UserManager\e-suite.Modules.UserManager\e-suite.Modules.UserManager.csproj" />
|
<ProjectReference Include="..\..\e-suite.Modules.UserManager\e-suite.Modules.UserManager\e-suite.Modules.UserManager.csproj" />
|
||||||
|
<ProjectReference Include="..\..\e-suite.Modules.WorkflowTemplatesManager\e-suite.Modules.WorkflowTemplatesManager.csproj" />
|
||||||
<ProjectReference Include="..\..\e-suite.Service.CustomFieldValidation\e-suite.Service.CustomFieldValidation\e-suite.Service.CustomFieldValidation.csproj" />
|
<ProjectReference Include="..\..\e-suite.Service.CustomFieldValidation\e-suite.Service.CustomFieldValidation\e-suite.Service.CustomFieldValidation.csproj" />
|
||||||
<ProjectReference Include="..\..\e-suite.Service.Mail\e-suite.Service.Mail\e-suite.Service.Mail.csproj" />
|
<ProjectReference Include="..\..\e-suite.Service.Mail\e-suite.Service.Mail\e-suite.Service.Mail.csproj" />
|
||||||
<ProjectReference Include="..\..\e-suite.Service.Sentinel\e-suite.Service.Sentinel\e-suite.Service.Sentinel.csproj" />
|
<ProjectReference Include="..\..\e-suite.Service.Sentinel\e-suite.Service.Sentinel\e-suite.Service.Sentinel.csproj" />
|
||||||
|
|||||||
@ -3,6 +3,5 @@
|
|||||||
public class TaskDefinition
|
public class TaskDefinition
|
||||||
{
|
{
|
||||||
public string Type { get; set; } = string.Empty;
|
public string Type { get; set; } = string.Empty;
|
||||||
public int Order { get; set; }
|
|
||||||
public Dictionary<string, object>? Config { get; set; }
|
public Dictionary<string, object>? Config { get; set; }
|
||||||
}
|
}
|
||||||
@ -1,5 +1,6 @@
|
|||||||
using e_suite.Database.Audit.Attributes;
|
using e_suite.Database.Audit.Attributes;
|
||||||
using e_suite.Database.Core.Models;
|
using e_suite.Database.Core.Models;
|
||||||
|
using e_suite.Database.Core.Tables.Forms;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using System.ComponentModel;
|
using System.ComponentModel;
|
||||||
using System.ComponentModel.DataAnnotations;
|
using System.ComponentModel.DataAnnotations;
|
||||||
@ -30,4 +31,6 @@ public class Workflow : IGeneralId, ISoftDeletable
|
|||||||
|
|
||||||
[AuditLastUpdated]
|
[AuditLastUpdated]
|
||||||
public DateTimeOffset LastUpdated { get; set; }
|
public DateTimeOffset LastUpdated { get; set; }
|
||||||
|
|
||||||
|
public ICollection<WorkflowVersion> Versions { get; set; } = [];
|
||||||
}
|
}
|
||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,8 @@
|
|||||||
|
// This file is used by Code Analysis to maintain SuppressMessage
|
||||||
|
// attributes that are applied to this project.
|
||||||
|
// Project-level suppressions either have no target or are given
|
||||||
|
// a specific target and scoped to a namespace, type, member, etc.
|
||||||
|
|
||||||
|
using System.Diagnostics.CodeAnalysis;
|
||||||
|
|
||||||
|
[assembly: SuppressMessage("Style", "IDE0290:Use primary constructor", Justification = "Primary constructors do not create readonly fields, it creates writable properties instead, which is bad practice", Scope = "module")]
|
||||||
17
e-suite.Modules.WorkflowTemplatesManager/IocRegistration.cs
Normal file
17
e-suite.Modules.WorkflowTemplatesManager/IocRegistration.cs
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
using Autofac;
|
||||||
|
using e_suite.API.Common;
|
||||||
|
using e_suite.API.Common.repository;
|
||||||
|
using e_suite.DependencyInjection;
|
||||||
|
using e_suite.Modules.WorkflowTemplatesManager.Repository;
|
||||||
|
|
||||||
|
namespace e_suite.Modules.WorkflowTemplatesManager;
|
||||||
|
|
||||||
|
public class IocRegistration : IIocRegistration
|
||||||
|
{
|
||||||
|
public void RegisterTypes(ContainerBuilder builder)
|
||||||
|
{
|
||||||
|
builder.RegisterType<WorkflowTemplateRepository>().As<IWorkflowTemplateRepository>().InstancePerLifetimeScope();
|
||||||
|
builder.RegisterType<WorkflowTemplateManager>().As<IWorkflowTemplateManager>().InstancePerLifetimeScope();
|
||||||
|
builder.RegisterType<WorkflowConverter>().As<IWorkflowConverter>().InstancePerLifetimeScope();
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,22 +1,113 @@
|
|||||||
using e_suite.API.Common.repository;
|
using e_suite.API.Common.repository;
|
||||||
using e_suite.Database.Audit;
|
using e_suite.Database.Audit;
|
||||||
using e_suite.Database.Core;
|
using e_suite.Database.Core;
|
||||||
using e_suite.Database.Core.Tables.Workflow;
|
using e_suite.Database.Core.Extensions;
|
||||||
|
using e_suite.Workflow.Core;
|
||||||
|
using e_suite.Workflow.Core.Extensions;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
|
||||||
namespace e_suite.Modules.WorkflowTemplatesManager.Repository;
|
namespace e_suite.Modules.WorkflowTemplatesManager.Repository;
|
||||||
|
|
||||||
|
public interface IWorkflowConverter
|
||||||
|
{
|
||||||
|
WorkflowVersion DeserialiseFromDatabase(e_suite.Database.Core.Tables.Workflow.WorkflowVersion dbVersion);
|
||||||
|
|
||||||
|
Task<e_suite.Database.Core.Tables.Workflow.WorkflowVersion> SerialiseToDatabase(
|
||||||
|
WorkflowVersion runtime,
|
||||||
|
e_suite.Database.Core.Tables.Workflow.WorkflowVersion? dbObject = null,
|
||||||
|
CancellationToken cancellationToken = default
|
||||||
|
);
|
||||||
|
}
|
||||||
|
public class WorkflowConverter : IWorkflowConverter
|
||||||
|
{
|
||||||
|
private readonly IDomainRepository _domainRepository;
|
||||||
|
|
||||||
|
public WorkflowConverter(IDomainRepository domainRepository)
|
||||||
|
{
|
||||||
|
_domainRepository = domainRepository;
|
||||||
|
}
|
||||||
|
|
||||||
|
public WorkflowVersion DeserialiseFromDatabase(e_suite.Database.Core.Tables.Workflow.WorkflowVersion dbVersion)
|
||||||
|
{
|
||||||
|
var runtime = new WorkflowVersion
|
||||||
|
{
|
||||||
|
Id = dbVersion.Id,
|
||||||
|
Guid = dbVersion.Guid,
|
||||||
|
Version = dbVersion.Version,
|
||||||
|
ActivityNameTemplate = dbVersion.ActivityNameTemplate,
|
||||||
|
Description = dbVersion.Description,
|
||||||
|
Domain = dbVersion.Domain.ToGeneralIdRef()!,
|
||||||
|
Template = new WorkflowTemplate
|
||||||
|
{
|
||||||
|
Name = "Need to fix",
|
||||||
|
Id = 1,
|
||||||
|
Guid = Guid.Empty
|
||||||
|
} // however you load templates
|
||||||
|
};
|
||||||
|
|
||||||
|
foreach (var def in dbVersion.Tasks)
|
||||||
|
{
|
||||||
|
var task = def.ToTask();
|
||||||
|
runtime.Tasks.Add(task);
|
||||||
|
}
|
||||||
|
|
||||||
|
return runtime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<e_suite.Database.Core.Tables.Workflow.WorkflowVersion> SerialiseToDatabase(WorkflowVersion runtime, e_suite.Database.Core.Tables.Workflow.WorkflowVersion? dbObject = null, CancellationToken cancellationToken = default)
|
||||||
|
{
|
||||||
|
if (runtime is null)
|
||||||
|
throw new NullReferenceException();
|
||||||
|
|
||||||
|
var domain = await _domainRepository.GetDomainById(runtime.Domain, cancellationToken);
|
||||||
|
if (domain is null)
|
||||||
|
throw new Exception($"Domain with id {runtime.Domain} not found.");
|
||||||
|
|
||||||
|
var dbVersion = dbObject ?? new e_suite.Database.Core.Tables.Workflow.WorkflowVersion();
|
||||||
|
|
||||||
|
if (dbObject == null)
|
||||||
|
{
|
||||||
|
dbVersion.Id = runtime.Id;
|
||||||
|
dbVersion.Guid = runtime.Guid;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//note cannot move a version from one workflow to another, that requires a new version.
|
||||||
|
//todo make sure that the Workflow is populated here.
|
||||||
|
//dbVersion.Workflow = runtime.Template.ToGeneralIdRef()
|
||||||
|
}
|
||||||
|
|
||||||
|
dbVersion.Version = runtime.Version; //todo make sure that the version number get incremented somewhere logical.
|
||||||
|
dbVersion.ActivityNameTemplate = runtime.ActivityNameTemplate;
|
||||||
|
dbVersion.Description = runtime.Description;
|
||||||
|
dbVersion.DomainId = domain.Id;
|
||||||
|
dbVersion.Tasks = runtime.Tasks
|
||||||
|
.Select(t => t.ToDefinition())
|
||||||
|
.ToList();
|
||||||
|
|
||||||
|
return dbVersion;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public class WorkflowTemplateRepository : RepositoryBase, IWorkflowTemplateRepository
|
public class WorkflowTemplateRepository : RepositoryBase, IWorkflowTemplateRepository
|
||||||
{
|
{
|
||||||
public WorkflowTemplateRepository(IEsuiteDatabaseDbContext databaseDbContext) : base(databaseDbContext)
|
public WorkflowTemplateRepository(IEsuiteDatabaseDbContext databaseDbContext) : base(databaseDbContext)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public IQueryable<WorkflowVersion> GetWorkflowVersions()
|
public IQueryable<e_suite.Database.Core.Tables.Workflow.Workflow> GetWorkflows()
|
||||||
|
{
|
||||||
|
return DatabaseDbContext.Workflows
|
||||||
|
.Include( x => x.Versions);
|
||||||
|
}
|
||||||
|
|
||||||
|
public IQueryable<e_suite.Database.Core.Tables.Workflow.WorkflowVersion> GetWorkflowVersions()
|
||||||
{
|
{
|
||||||
return DatabaseDbContext.WorkflowVersions;
|
return DatabaseDbContext.WorkflowVersions;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task EditWorkflowVersionAsync(AuditUserDetails auditUserDetails, WorkflowVersion workflowVersion, CancellationToken cancellationToken)
|
public async Task EditWorkflowVersionAsync(AuditUserDetails auditUserDetails, e_suite.Database.Core.Tables.Workflow.WorkflowVersion workflowVersion, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
await DatabaseDbContext.SaveChangesAsync(auditUserDetails, cancellationToken);
|
await DatabaseDbContext.SaveChangesAsync(auditUserDetails, cancellationToken);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,16 +3,19 @@ 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;
|
||||||
using e_suite.Database.Core.Extensions;
|
using e_suite.Database.Core.Extensions;
|
||||||
using e_suite.Database.Core.Tables.Workflow;
|
|
||||||
using e_suite.Utilities.Pagination;
|
using e_suite.Utilities.Pagination;
|
||||||
using eSuite.Core.Miscellaneous;
|
using eSuite.Core.Miscellaneous;
|
||||||
using System.Linq.Expressions;
|
using System.Linq.Expressions;
|
||||||
|
using e_suite.Modules.WorkflowTemplatesManager.Repository;
|
||||||
|
|
||||||
|
//using WorkflowVersion = e_suite.Workflow.Core.WorkflowVersion;
|
||||||
|
|
||||||
namespace e_suite.Modules.WorkflowTemplatesManager;
|
namespace e_suite.Modules.WorkflowTemplatesManager;
|
||||||
|
|
||||||
public class WorkflowTemplateManager : IWorkflowTemplateManager
|
public class WorkflowTemplateManager : IWorkflowTemplateManager
|
||||||
{
|
{
|
||||||
private readonly IWorkflowTemplateRepository _workflowTemplateRepository;
|
private readonly IWorkflowTemplateRepository _workflowTemplateRepository;
|
||||||
|
private readonly IWorkflowConverter _workflowConverter;
|
||||||
private readonly IDomainRepository _domainRepository;
|
private readonly IDomainRepository _domainRepository;
|
||||||
private readonly IPatchFactory _patchFactory;
|
private readonly IPatchFactory _patchFactory;
|
||||||
|
|
||||||
@ -24,16 +27,38 @@ public class WorkflowTemplateManager : IWorkflowTemplateManager
|
|||||||
}
|
}
|
||||||
|
|
||||||
public async Task<PaginatedData<GetWorkflowTemplate>> GetWorkflowTemplatesAsync(Paging paging, CancellationToken cancellationToken)
|
public async Task<PaginatedData<GetWorkflowTemplate>> GetWorkflowTemplatesAsync(Paging paging, CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
var ssoProviders = _workflowTemplateRepository.GetWorkflows().Where(x => x.Deleted == false);
|
||||||
|
|
||||||
|
var paginatedData = await PaginatedData.Paginate<e_suite.Database.Core.Tables.Workflow.Workflow, GetWorkflowTemplate>(ssoProviders, paging,
|
||||||
|
WorkflowKeySelector, cancellationToken);
|
||||||
|
|
||||||
|
return paginatedData;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Expression<Func<e_suite.Database.Core.Tables.Workflow.Workflow, object>> WorkflowKeySelector(string sortKey)
|
||||||
|
{
|
||||||
|
return sortKey?.ToLowerInvariant() switch
|
||||||
|
{
|
||||||
|
"id" => x => x.Id,
|
||||||
|
"guid" => x => x.Guid,
|
||||||
|
"name" => x => x.Name,
|
||||||
|
"lastupdated" => x => x.LastUpdated,
|
||||||
|
_ => x => x.Id
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<PaginatedData<GetWorkflowTemplateVersion>> GetWorkflowTemplateVersionsAsync(Paging paging, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
var ssoProviders = _workflowTemplateRepository.GetWorkflowVersions().Where(x => x.Deleted == false);
|
var ssoProviders = _workflowTemplateRepository.GetWorkflowVersions().Where(x => x.Deleted == false);
|
||||||
|
|
||||||
var paginatedData = await PaginatedData.Paginate<WorkflowVersion, GetWorkflowTemplate>(ssoProviders, paging,
|
var paginatedData = await PaginatedData.Paginate<e_suite.Database.Core.Tables.Workflow.WorkflowVersion, GetWorkflowTemplateVersion>(ssoProviders, paging,
|
||||||
KeySelector, cancellationToken);
|
KeySelector, cancellationToken);
|
||||||
|
|
||||||
return paginatedData;
|
return paginatedData;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Expression<Func<WorkflowVersion, object>> KeySelector(string sortKey)
|
private Expression<Func<e_suite.Database.Core.Tables.Workflow.WorkflowVersion, object>> KeySelector(string sortKey)
|
||||||
{
|
{
|
||||||
return sortKey?.ToLowerInvariant() switch
|
return sortKey?.ToLowerInvariant() switch
|
||||||
{
|
{
|
||||||
@ -46,24 +71,23 @@ public class WorkflowTemplateManager : IWorkflowTemplateManager
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<GetWorkflowTemplate?> GetWorkflowTemplateAsync(GeneralIdRef generalIdRef, CancellationToken cancellationToken)
|
public async Task<GetWorkflowTemplateVersion?> GetWorkflowTemplateVersionAsync(GeneralIdRef generalIdRef, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
var workflowTemplate = await _workflowTemplateRepository.GetWorkflowVersions().FindByGeneralIdRefAsync(generalIdRef, cancellationToken)
|
var dbWorkflowTemplate = await _workflowTemplateRepository.GetWorkflowVersions().FindByGeneralIdRefAsync(generalIdRef, cancellationToken) ?? throw new NotFoundException("Unable to find Workflow Version");
|
||||||
?? throw new NotFoundException("Unable to find Workflow Version");
|
//var workflowTemplate = _workflowConverter.DeserialiseFromDatabase(dbWorkflowTemplate);
|
||||||
return new GetWorkflowTemplate(workflowTemplate);
|
|
||||||
|
return new GetWorkflowTemplateVersion(dbWorkflowTemplate);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task EditTemplate(
|
public async Task EditTemplateVersion(
|
||||||
AuditUserDetails auditUserDetails,
|
AuditUserDetails auditUserDetails,
|
||||||
EditWorkflowTemplate template,
|
EditWorkflowTemplateVersion template,
|
||||||
CancellationToken cancellationToken
|
CancellationToken cancellationToken
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
await AlterWorkflowTemplateVersionAsync(auditUserDetails, template.ToGeneralIdRef()!, async version =>
|
await AlterWorkflowTemplateVersionAsync(auditUserDetails, template.ToGeneralIdRef()!, async version =>
|
||||||
{
|
{
|
||||||
var domain = await _domainRepository.GetDomainById(template.DomainId, cancellationToken);
|
var domain = await _domainRepository.GetDomainById(template.DomainId!, cancellationToken) ?? throw new NotFoundException("Unable to find Domain with provided id");
|
||||||
if (domain is null)
|
|
||||||
throw new NotFoundException("Unable to find Domain with provided id");
|
|
||||||
|
|
||||||
version.Domain = domain;
|
version.Domain = domain;
|
||||||
version.DomainId = domain.Id;
|
version.DomainId = domain.Id;
|
||||||
@ -71,34 +95,37 @@ public class WorkflowTemplateManager : IWorkflowTemplateManager
|
|||||||
version.ActivityNameTemplate = template.ActivityNameTemplate;
|
version.ActivityNameTemplate = template.ActivityNameTemplate;
|
||||||
version.Deleted = false;
|
version.Deleted = false;
|
||||||
version.Version = template.Version;
|
version.Version = template.Version;
|
||||||
//version.WorkflowId
|
version.Tasks = template.Tasks;
|
||||||
}, cancellationToken);
|
}, cancellationToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task PatchTemplate(
|
public async Task PatchTemplateVersion(
|
||||||
AuditUserDetails auditUserDetails,
|
AuditUserDetails auditUserDetails,
|
||||||
IGeneralIdRef templateId,
|
IGeneralIdRef templateId,
|
||||||
PatchWorkflowTemplate patchTemplate,
|
PatchWorkflowTemplateVersion patchTemplate,
|
||||||
CancellationToken cancellationToken
|
CancellationToken cancellationToken
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
var patch = _patchFactory.Create(patchTemplate);
|
var patch = _patchFactory.Create(patchTemplate);
|
||||||
await AlterWorkflowTemplateVersionAsync(auditUserDetails, templateId, async version =>
|
await AlterWorkflowTemplateVersionAsync(auditUserDetails, templateId, async version =>
|
||||||
{
|
{
|
||||||
patch.ApplyTo(version);
|
await patch.ApplyTo(version);
|
||||||
}, cancellationToken);
|
}, cancellationToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task PostTemplate(
|
public async Task PostTemplateVersion(
|
||||||
AuditUserDetails auditUserDetails,
|
AuditUserDetails auditUserDetails,
|
||||||
CreateWorkflowTemplate template,
|
CreateWorkflowTemplateVersion template,
|
||||||
CancellationToken cancellationToken
|
CancellationToken cancellationToken
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
//var workflowTemplate = _workflowConverter.DeserialiseFromDatabase(dbWorkflowTemplate);
|
||||||
|
|
||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task DeleteTemplate(AuditUserDetails auditUserDetails, IGeneralIdRef templateId, CancellationToken cancellationToken)
|
public async Task DeleteTemplateVersion(AuditUserDetails auditUserDetails, IGeneralIdRef templateId, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
await AlterWorkflowTemplateVersionAsync(auditUserDetails, templateId, async version =>
|
await AlterWorkflowTemplateVersionAsync(auditUserDetails, templateId, async version =>
|
||||||
{
|
{
|
||||||
@ -109,15 +136,13 @@ public class WorkflowTemplateManager : IWorkflowTemplateManager
|
|||||||
private async Task AlterWorkflowTemplateVersionAsync(
|
private async Task AlterWorkflowTemplateVersionAsync(
|
||||||
AuditUserDetails auditUserDetails,
|
AuditUserDetails auditUserDetails,
|
||||||
IGeneralIdRef generalIdRef,
|
IGeneralIdRef generalIdRef,
|
||||||
Func<WorkflowVersion, Task> applyChanges,
|
Func<e_suite.Database.Core.Tables.Workflow.WorkflowVersion, Task> applyChanges,
|
||||||
CancellationToken cancellationToken
|
CancellationToken cancellationToken
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
await _workflowTemplateRepository.TransactionAsync(async () =>
|
await _workflowTemplateRepository.TransactionAsync(async () =>
|
||||||
{
|
{
|
||||||
var workflowVersion = await _workflowTemplateRepository.GetWorkflowVersions().FindByGeneralIdRefAsync(generalIdRef, cancellationToken);
|
var workflowVersion = await _workflowTemplateRepository.GetWorkflowVersions().FindByGeneralIdRefAsync(generalIdRef, cancellationToken) ?? throw new NotFoundException("SsoProvider with this id does not exists");
|
||||||
if (workflowVersion is null)
|
|
||||||
throw new NotFoundException("SsoProvider with this id does not exists");
|
|
||||||
|
|
||||||
await applyChanges(workflowVersion);
|
await applyChanges(workflowVersion);
|
||||||
|
|
||||||
|
|||||||
@ -1,38 +1,105 @@
|
|||||||
using e_suite.Workflow.Core.Attributes;
|
using e_suite.Database.Core.Models;
|
||||||
using e_suite.Workflow.Core.Enums;
|
using e_suite.Workflow.Core.Attributes;
|
||||||
using e_suite.Workflow.Core.Interfaces;
|
using e_suite.Workflow.Core.Interfaces;
|
||||||
using e_suite.Workflow.Core.Tasks;
|
using System.Reflection;
|
||||||
|
|
||||||
namespace e_suite.Workflow.Core.Extensions;
|
namespace e_suite.Workflow.Core.Extensions;
|
||||||
|
|
||||||
//copied from Database.core.
|
|
||||||
public class TaskDefinition
|
|
||||||
{
|
|
||||||
public string Type { get; set; } = string.Empty;
|
|
||||||
public int Order { get; set; }
|
|
||||||
public Dictionary<string, object>? Config { get; set; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class TaskExtensions
|
public static class TaskExtensions
|
||||||
{
|
{
|
||||||
public static TaskDefinition ToDefinition(this ITask task, int order)
|
private static Dictionary<string, object?> ToConfigDictionary(this ITask task)
|
||||||
{
|
{
|
||||||
if (task is ITemplateValidatable v)
|
var dictionary = new Dictionary<string, object?>();
|
||||||
|
|
||||||
|
var type = task.GetType();
|
||||||
|
var properties = type.GetProperties(BindingFlags.Public | BindingFlags.Instance);
|
||||||
|
|
||||||
|
foreach (var prop in properties)
|
||||||
{
|
{
|
||||||
var errors = v.ValidateForTemplate().ToList();
|
if (!prop.CanRead)
|
||||||
if (errors.Count != 0)
|
continue;
|
||||||
throw new InvalidOperationException(
|
|
||||||
$"Task {task.GetType().Name} is invalid: {string.Join("; ", errors)}");
|
if (!prop.CanWrite)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
var value = prop.GetValue(task);
|
||||||
|
|
||||||
|
dictionary[prop.Name] = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return dictionary;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ITask ToTask(this TaskDefinition definition)
|
||||||
|
{
|
||||||
|
var type = Type.GetType(definition.Type);
|
||||||
|
|
||||||
|
if (type == null)
|
||||||
|
throw new InvalidOperationException($"Unknown task type '{definition.Type}'.");
|
||||||
|
|
||||||
|
var instance = Activator.CreateInstance(type) as ITask;
|
||||||
|
|
||||||
|
if (instance == null)
|
||||||
|
throw new InvalidOperationException($"Type '{definition.Type}' does not implement ITask.");
|
||||||
|
|
||||||
|
FromConfigDictionary(instance, definition.Config);
|
||||||
|
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void FromConfigDictionary(this object obj, Dictionary<string, object?> dict)
|
||||||
|
{
|
||||||
|
var type = obj.GetType();
|
||||||
|
|
||||||
|
foreach (var kvp in dict)
|
||||||
|
{
|
||||||
|
var prop = type.GetProperty(kvp.Key);
|
||||||
|
if (prop == null || !prop.CanWrite)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
var targetType = prop.PropertyType;
|
||||||
|
var value = kvp.Value;
|
||||||
|
|
||||||
|
// Handle enums (the only case where JSON gives you a string)
|
||||||
|
if (value != null && targetType.IsEnum)
|
||||||
|
{
|
||||||
|
value = Enum.Parse(targetType, value.ToString()!, ignoreCase: true);
|
||||||
|
}
|
||||||
|
|
||||||
|
prop.SetValue(obj, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static TaskDefinition ToDefinition(this ITask task)
|
||||||
|
{
|
||||||
|
if (task is null)
|
||||||
|
throw new NullReferenceException();
|
||||||
|
|
||||||
|
|
||||||
return new TaskDefinition
|
return new TaskDefinition
|
||||||
{
|
{
|
||||||
Type = task.GetType().AssemblyQualifiedName!,
|
Type = task.GetType().AssemblyQualifiedName,
|
||||||
Order = order,
|
Config = task.ToConfigDictionary()
|
||||||
Config = ExtractConfig(task)
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//public static TaskDefinition ToDefinition(this ITask task)
|
||||||
|
//{
|
||||||
|
// if (task is ITemplateValidatable v)
|
||||||
|
// {
|
||||||
|
// var errors = v.ValidateForTemplate().ToList();
|
||||||
|
// if (errors.Count != 0)
|
||||||
|
// throw new InvalidOperationException(
|
||||||
|
// $"Task {task.GetType().Name} is invalid: {string.Join("; ", errors)}");
|
||||||
|
// }
|
||||||
|
|
||||||
|
// return new TaskDefinition
|
||||||
|
// {
|
||||||
|
// Type = task.GetType().AssemblyQualifiedName!,
|
||||||
|
// Config = ExtractConfig(task)
|
||||||
|
// };
|
||||||
|
//}
|
||||||
|
|
||||||
private static Dictionary<string, object> ExtractConfig(object task)
|
private static Dictionary<string, object> ExtractConfig(object task)
|
||||||
{
|
{
|
||||||
var dict = new Dictionary<string, object>();
|
var dict = new Dictionary<string, object>();
|
||||||
@ -52,53 +119,53 @@ public static class TaskExtensions
|
|||||||
return dict;
|
return dict;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ITask ToTask(this TaskDefinition def)
|
//public static ITask ToTask(this TaskDefinition def)
|
||||||
{
|
//{
|
||||||
var type = Type.GetType(def.Type, throwOnError: true)!;
|
// var type = Type.GetType(def.Type, throwOnError: true)!;
|
||||||
var task = (ITask)Activator.CreateInstance(type)!;
|
// var task = (ITask)Activator.CreateInstance(type)!;
|
||||||
|
|
||||||
if (def.Config != null)
|
// if (def.Config != null)
|
||||||
foreach (var kvp in def.Config)
|
// foreach (var kvp in def.Config)
|
||||||
{
|
// {
|
||||||
var prop = type.GetProperty(kvp.Key);
|
// var prop = type.GetProperty(kvp.Key);
|
||||||
if (prop == null || !prop.CanWrite) continue;
|
// if (prop == null || !prop.CanWrite) continue;
|
||||||
if (prop.IsDefined(typeof(RuntimeOnlyAttribute), inherit: true))
|
// if (prop.IsDefined(typeof(RuntimeOnlyAttribute), inherit: true))
|
||||||
continue;
|
// continue;
|
||||||
|
|
||||||
object? converted = ConvertValue(kvp.Value, prop.PropertyType);
|
// object? converted = ConvertValue(kvp.Value, prop.PropertyType);
|
||||||
prop.SetValue(task, converted);
|
// prop.SetValue(task, converted);
|
||||||
}
|
// }
|
||||||
|
|
||||||
if (task is ITemplateValidatable v)
|
// if (task is ITemplateValidatable v)
|
||||||
{
|
// {
|
||||||
var errors = v.ValidateForTemplate().ToList();
|
// var errors = v.ValidateForTemplate().ToList();
|
||||||
if (errors.Count != 0)
|
// if (errors.Count != 0)
|
||||||
throw new InvalidOperationException(
|
// throw new InvalidOperationException(
|
||||||
$"Task {task.GetType().Name} is invalid: {string.Join("; ", errors)}");
|
// $"Task {task.GetType().Name} is invalid: {string.Join("; ", errors)}");
|
||||||
}
|
// }
|
||||||
|
|
||||||
return task;
|
// return task;
|
||||||
}
|
//}
|
||||||
|
|
||||||
private static object? ConvertValue(object? value, Type targetType)
|
//private static object? ConvertValue(object? value, Type targetType)
|
||||||
{
|
//{
|
||||||
if (value == null) return null;
|
// if (value == null) return null;
|
||||||
|
|
||||||
// Handle enums
|
// // Handle enums
|
||||||
if (targetType.IsEnum)
|
// if (targetType.IsEnum)
|
||||||
return Enum.Parse(targetType, value.ToString()!);
|
// return Enum.Parse(targetType, value.ToString()!);
|
||||||
|
|
||||||
// Handle Guid
|
// // Handle Guid
|
||||||
if (targetType == typeof(Guid))
|
// if (targetType == typeof(Guid))
|
||||||
return Guid.Parse(value.ToString()!);
|
// return Guid.Parse(value.ToString()!);
|
||||||
|
|
||||||
// Handle nullable types
|
// // Handle nullable types
|
||||||
var underlying = Nullable.GetUnderlyingType(targetType);
|
// var underlying = Nullable.GetUnderlyingType(targetType);
|
||||||
if (underlying != null)
|
// if (underlying != null)
|
||||||
return Convert.ChangeType(value, underlying);
|
// return Convert.ChangeType(value, underlying);
|
||||||
|
|
||||||
return Convert.ChangeType(value, targetType);
|
// return Convert.ChangeType(value, targetType);
|
||||||
}
|
//}
|
||||||
|
|
||||||
|
|
||||||
//Todo can only be on a run-time instance
|
//Todo can only be on a run-time instance
|
||||||
|
|||||||
@ -1,17 +1,17 @@
|
|||||||
using e_suite.Workflow.Core.Interfaces;
|
using e_suite.Workflow.Core.Interfaces;
|
||||||
|
|
||||||
namespace e_suite.Workflow.Core.Extensions;
|
namespace e_suite.Workflow.Core.Extensions;
|
||||||
|
public static class WorkflowVersionExtensions
|
||||||
public static class WorkflowExtensions
|
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Returns true once the workflow has met any requirements that are needed to change the state to active.
|
/// Returns true once the workflow has met any requirements that are needed to change the state to active.
|
||||||
/// For example, earliest start time has passed.
|
/// For example, earliest start time has passed.
|
||||||
/// Or required starting information is now available.
|
/// Or required starting information is now available.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static bool ReadyToActivate(this IWorkflow workflow)
|
public static bool ReadyToActivate(this IWorkflowVersion workflow)
|
||||||
{
|
{
|
||||||
//todo Check to see if the StartDate has passed.
|
//todo Check to see if the StartDate has passed.
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -12,7 +12,7 @@ public interface ITask
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// ID of the parent of this task. It could be either a Task or a Workflow.
|
/// ID of the parent of this task. It could be either a Task or a Workflow.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
ITask Parent { get; }
|
ITask Parent { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Name of the task as seen by users, must be unique in the workflow.
|
/// Name of the task as seen by users, must be unique in the workflow.
|
||||||
|
|||||||
@ -4,7 +4,7 @@ using eSuite.Core.Miscellaneous;
|
|||||||
|
|
||||||
namespace e_suite.Workflow.Core.Interfaces;
|
namespace e_suite.Workflow.Core.Interfaces;
|
||||||
|
|
||||||
public interface IWorkflow : IStage<GeneralTaskAttribute>
|
public interface IWorkflowVersion : IStage<GeneralTaskAttribute>
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Client domain to which the workflow belongs.
|
/// Client domain to which the workflow belongs.
|
||||||
|
|||||||
@ -16,7 +16,7 @@ public class WorkflowTemplate: IGeneralId
|
|||||||
public required string Name { get; set; }
|
public required string Name { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class WorkflowVersion : IGeneralId, IWorkflow
|
public class WorkflowVersion : IGeneralId, IWorkflowVersion
|
||||||
{
|
{
|
||||||
public long Id { get; set; }
|
public long Id { get; set; }
|
||||||
public Guid Guid { get; set; }
|
public Guid Guid { get; set; }
|
||||||
@ -25,7 +25,7 @@ public class WorkflowVersion : IGeneralId, IWorkflow
|
|||||||
|
|
||||||
public required long Version { get; set; }
|
public required long Version { get; set; }
|
||||||
|
|
||||||
public ICollection<ITask> Tasks { get; } = new List<ITask>(); //Serialise to Json.
|
public ICollection<ITask> Tasks { get; } = []; //Serialise to Json.
|
||||||
public required IGeneralIdRef Domain { get; set; }
|
public required IGeneralIdRef Domain { get; set; }
|
||||||
public WorkflowState CurrentState { get; set; } = WorkflowState.Pending;
|
public WorkflowState CurrentState { get; set; } = WorkflowState.Pending;
|
||||||
public required string ActivityNameTemplate { get; set; }
|
public required string ActivityNameTemplate { get; set; }
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,6 +1,7 @@
|
|||||||
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
|
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=authorisation/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=authorisation/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Authorised/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=Authorised/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=Deserialise/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=execption/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=execption/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=jwks/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=jwks/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=organisation/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=organisation/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user