diff --git a/src/Squidex/Areas/Api/Controllers/Apps/AppWorkflowsController.cs b/src/Squidex/Areas/Api/Controllers/Apps/AppWorkflowsController.cs index be489f20e..abc16700a 100644 --- a/src/Squidex/Areas/Api/Controllers/Apps/AppWorkflowsController.cs +++ b/src/Squidex/Areas/Api/Controllers/Apps/AppWorkflowsController.cs @@ -5,11 +5,13 @@ // All rights reserved. Licensed under the MIT license. // ========================================================================== +using System; using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc; using Microsoft.Net.Http.Headers; using Squidex.Areas.Api.Controllers.Apps.Models; using Squidex.Domain.Apps.Entities.Apps; +using Squidex.Domain.Apps.Entities.Apps.Commands; using Squidex.Infrastructure.Commands; using Squidex.Shared; using Squidex.Web; @@ -36,13 +38,13 @@ namespace Squidex.Areas.Api.Controllers.Apps /// 404 => App not found. /// [HttpGet] - [Route("apps/{app}/workflow/")] - [ProducesResponseType(typeof(WorkflowResponseDto), 200)] + [Route("apps/{app}/workflows/")] + [ProducesResponseType(typeof(WorkflowsDto), 200)] [ApiPermission(Permissions.AppWorkflowsRead)] [ApiCosts(0)] - public IActionResult GetWorkflow(string app) + public IActionResult GetWorkflows(string app) { - var response = WorkflowResponseDto.FromApp(App, this); + var response = WorkflowsDto.FromApp(App, this); Response.Headers[HeaderNames.ETag] = App.Version.ToString(); @@ -50,21 +52,46 @@ namespace Squidex.Areas.Api.Controllers.Apps } /// - /// Configure workflow of the app. + /// Create a workflow. /// /// The name of the app. /// The new workflow. /// - /// 200 => Workflow configured. - /// 400 => Workflow is not valid. - /// 404 => App not found. + /// 200 => Workflow updated. + /// 400 => Workflow request is not valid. + /// 404 => Workflow or app not found. + /// + [HttpPost] + [Route("apps/{app}/workflows/")] + [ProducesResponseType(typeof(WorkflowsDto), 200)] + [ApiPermission(Permissions.AppWorkflowsUpdate)] + [ApiCosts(1)] + public async Task PostWorkflow(string app, [FromBody] AddWorkflowDto request) + { + var command = request.ToCommand(); + + var response = await InvokeCommandAsync(command); + + return Ok(response); + } + + /// + /// Update a workflow. + /// + /// The name of the app. + /// The new workflow. + /// The id of the workflow to update. + /// + /// 200 => Workflow updated. + /// 400 => Workflow request is not valid. + /// 404 => Workflow or app not found. /// [HttpPut] - [Route("apps/{app}/workflow/")] - [ProducesResponseType(typeof(WorkflowResponseDto), 200)] + [Route("apps/{app}/workflows/{id}")] + [ProducesResponseType(typeof(WorkflowsDto), 200)] [ApiPermission(Permissions.AppWorkflowsUpdate)] [ApiCosts(1)] - public async Task PutWorkflow(string app, [FromBody] UpsertWorkflowDto request) + public async Task PutWorkflow(string app, Guid id, [FromBody] UpdateWorkflowDto request) { var command = request.ToCommand(); @@ -73,12 +100,35 @@ namespace Squidex.Areas.Api.Controllers.Apps return Ok(response); } - private async Task InvokeCommandAsync(ICommand command) + /// + /// Delete a workflow. + /// + /// The name of the app. + /// The id of the workflow to update. + /// + /// 200 => Workflow deleted. + /// 404 => Workflow or app not found. + /// + [HttpDelete] + [Route("apps/{app}/workflows/{id}")] + [ProducesResponseType(typeof(WorkflowsDto), 200)] + [ApiPermission(Permissions.AppWorkflowsUpdate)] + [ApiCosts(1)] + public async Task DeleteWorkflow(string app, Guid id) + { + var command = new DeleteWorkflow { WorkflowId = id }; + + var response = await InvokeCommandAsync(command); + + return Ok(response); + } + + private async Task InvokeCommandAsync(ICommand command) { var context = await CommandBus.PublishAsync(command); var result = context.Result(); - var response = WorkflowResponseDto.FromApp(result, this); + var response = WorkflowsDto.FromApp(result, this); return response; } diff --git a/src/Squidex/Areas/Api/Controllers/Apps/Models/WorkflowResponseDto.cs b/src/Squidex/Areas/Api/Controllers/Apps/Models/AddWorkflowDto.cs similarity index 53% rename from src/Squidex/Areas/Api/Controllers/Apps/Models/WorkflowResponseDto.cs rename to src/Squidex/Areas/Api/Controllers/Apps/Models/AddWorkflowDto.cs index 3186a7893..823794c6b 100644 --- a/src/Squidex/Areas/Api/Controllers/Apps/Models/WorkflowResponseDto.cs +++ b/src/Squidex/Areas/Api/Controllers/Apps/Models/AddWorkflowDto.cs @@ -6,27 +6,22 @@ // ========================================================================== using System.ComponentModel.DataAnnotations; -using Squidex.Domain.Apps.Entities.Apps; -using Squidex.Web; +using Squidex.Domain.Apps.Entities.Apps.Commands; +using Squidex.Infrastructure.Commands; namespace Squidex.Areas.Api.Controllers.Apps.Models { - public sealed class WorkflowResponseDto : Resource + public sealed class AddWorkflowDto { /// - /// The workflow. + /// The name of the workflow. /// [Required] - public WorkflowDto Workflow { get; set; } + public string Name { get; set; } - public static WorkflowResponseDto FromApp(IAppEntity app, ApiController controller) + public ICommand ToCommand() { - var result = new WorkflowResponseDto - { - Workflow = WorkflowDto.FromWorkflow(app.Workflows.GetFirst(), controller, app.Name) - }; - - return result; + return new AddWorkflow { Name = Name }; } } } diff --git a/src/Squidex/Areas/Api/Controllers/Apps/Models/AppDto.cs b/src/Squidex/Areas/Api/Controllers/Apps/Models/AppDto.cs index 46e37a1ea..ffa7b22fa 100644 --- a/src/Squidex/Areas/Api/Controllers/Apps/Models/AppDto.cs +++ b/src/Squidex/Areas/Api/Controllers/Apps/Models/AppDto.cs @@ -179,7 +179,7 @@ namespace Squidex.Areas.Api.Controllers.Apps.Models if (controller.HasPermission(AllPermissions.AppWorkflowsRead, Name, permissions: permissions)) { - AddGetLink("workflows", controller.Url(x => nameof(x.GetWorkflow), values)); + AddGetLink("workflows", controller.Url(x => nameof(x.GetWorkflows), values)); } if (controller.HasPermission(AllPermissions.AppSchemasCreate, Name, permissions: permissions)) diff --git a/src/Squidex/Areas/Api/Controllers/Apps/Models/UpsertWorkflowDto.cs b/src/Squidex/Areas/Api/Controllers/Apps/Models/UpdateWorkflowDto.cs similarity index 97% rename from src/Squidex/Areas/Api/Controllers/Apps/Models/UpsertWorkflowDto.cs rename to src/Squidex/Areas/Api/Controllers/Apps/Models/UpdateWorkflowDto.cs index 37577e9e5..6a7a23653 100644 --- a/src/Squidex/Areas/Api/Controllers/Apps/Models/UpsertWorkflowDto.cs +++ b/src/Squidex/Areas/Api/Controllers/Apps/Models/UpdateWorkflowDto.cs @@ -13,7 +13,7 @@ using Squidex.Domain.Apps.Entities.Apps.Commands; namespace Squidex.Areas.Api.Controllers.Apps.Models { - public sealed class UpsertWorkflowDto + public sealed class UpdateWorkflowDto { /// /// The workflow steps. diff --git a/src/Squidex/Areas/Api/Controllers/Apps/Models/WorkflowDto.cs b/src/Squidex/Areas/Api/Controllers/Apps/Models/WorkflowDto.cs index 3a6a3fecc..d347337da 100644 --- a/src/Squidex/Areas/Api/Controllers/Apps/Models/WorkflowDto.cs +++ b/src/Squidex/Areas/Api/Controllers/Apps/Models/WorkflowDto.cs @@ -5,6 +5,7 @@ // All rights reserved. Licensed under the MIT license. // ========================================================================== +using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.Linq; @@ -17,6 +18,11 @@ namespace Squidex.Areas.Api.Controllers.Apps.Models { public sealed class WorkflowDto : Resource { + /// + /// The workflow id. + /// + public Guid Id { get; set; } + /// /// The workflow steps. /// @@ -28,10 +34,11 @@ namespace Squidex.Areas.Api.Controllers.Apps.Models /// public Status Initial { get; set; } - public static WorkflowDto FromWorkflow(Workflow workflow, ApiController controller, string app) + public static WorkflowDto FromWorkflow(Guid id, Workflow workflow, ApiController controller, string app) { var result = new WorkflowDto { + Id = id, Steps = workflow.Steps.ToDictionary( x => x.Key, x => SimpleMapper.Map(x.Value, new WorkflowStepDto @@ -43,18 +50,23 @@ namespace Squidex.Areas.Api.Controllers.Apps.Models Initial = workflow.Initial }; - return result.CreateLinks(controller, app); + return result.CreateLinks(controller, app, id); } - private WorkflowDto CreateLinks(ApiController controller, string app) + private WorkflowDto CreateLinks(ApiController controller, string app, Guid id) { - var values = new { app }; + var values = new { app, id }; if (controller.HasPermission(Permissions.AppWorkflowsUpdate, app)) { AddPutLink("update", controller.Url(x => nameof(x.PutWorkflow), values)); } + if (controller.HasPermission(Permissions.AppWorkflowsDelete, app)) + { + AddDeleteLink("delete", controller.Url(x => nameof(x.DeleteWorkflow), values)); + } + return this; } } diff --git a/src/Squidex/Areas/Api/Controllers/Apps/Models/WorkflowsDto.cs b/src/Squidex/Areas/Api/Controllers/Apps/Models/WorkflowsDto.cs new file mode 100644 index 000000000..b58be115c --- /dev/null +++ b/src/Squidex/Areas/Api/Controllers/Apps/Models/WorkflowsDto.cs @@ -0,0 +1,49 @@ +// ========================================================================== +// Squidex Headless CMS +// ========================================================================== +// Copyright (c) Squidex UG (haftungsbeschraenkt) +// All rights reserved. Licensed under the MIT license. +// ========================================================================== + +using System; +using System.ComponentModel.DataAnnotations; +using System.Linq; +using Squidex.Domain.Apps.Entities.Apps; +using Squidex.Shared; +using Squidex.Web; + +namespace Squidex.Areas.Api.Controllers.Apps.Models +{ + public sealed class WorkflowsDto : Resource + { + /// + /// The workflow. + /// + [Required] + public WorkflowDto[] Items { get; set; } + + public static WorkflowsDto FromApp(IAppEntity app, ApiController controller) + { + var result = new WorkflowsDto + { + Items = app.Workflows.Select(x => WorkflowDto.FromWorkflow(x.Key, x.Value, controller, app.Name)).ToArray() + }; + + return result.CreateLinks(controller, app.Name); + } + + private WorkflowsDto CreateLinks(ApiController controller, string app) + { + var values = new { app }; + + AddSelfLink(controller.Url(x => nameof(x.GetWorkflows), values)); + + if (controller.HasPermission(Permissions.AppWorkflowsCreate, app)) + { + AddPostLink("create", controller.Url(x => nameof(x.PostWorkflow), values)); + } + + return this; + } + } +}