// ========================================================================== // Squidex Headless CMS // ========================================================================== // Copyright (c) Squidex UG (haftungsbeschränkt) // All rights reserved. Licensed under the MIT license. // ========================================================================== using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc; using Squidex.Areas.Api.Controllers.Schemas.Models; using Squidex.Domain.Apps.Entities.Schemas; using Squidex.Domain.Apps.Entities.Schemas.Commands; using Squidex.Infrastructure.Commands; using Squidex.Shared; using Squidex.Web; namespace Squidex.Areas.Api.Controllers.Schemas { /// /// Manages and retrieves information about schemas. /// [ApiExplorerSettings(GroupName = nameof(Schemas))] public sealed class SchemaFieldsController : ApiController { public SchemaFieldsController(ICommandBus commandBus) : base(commandBus) { } /// /// Add a schema field. /// /// The name of the app. /// The name of the schema. /// The field object that needs to be added to the schema. /// /// 201 => Schema field created. /// 400 => Schema field properties not valid. /// 404 => Schema or app not found. /// 409 => Schema field name already in use. /// [HttpPost] [Route("apps/{app}/schemas/{name}/fields/")] [ProducesResponseType(typeof(SchemaDetailsDto), 201)] [ApiPermission(Permissions.AppSchemasUpdate)] [ApiCosts(1)] public async Task PostField(string app, string name, [FromBody] AddFieldDto request) { var command = request.ToCommand(); var response = await InvokeCommandAsync(app, command); return CreatedAtAction(nameof(SchemasController.GetSchema), "Schemas", new { app, name }, response); } /// /// Add a nested schema field. /// /// The name of the app. /// The name of the schema. /// The parent field id. /// The field object that needs to be added to the schema. /// /// 201 => Schema field created. /// 400 => Schema field properties not valid. /// 409 => Schema field name already in use. /// 404 => Schema, field or app not found. /// [HttpPost] [Route("apps/{app}/schemas/{name}/fields/{parentId:long}/nested/")] [ProducesResponseType(typeof(SchemaDetailsDto), 201)] [ApiPermission(Permissions.AppSchemasUpdate)] [ApiCosts(1)] public async Task PostNestedField(string app, string name, long parentId, [FromBody] AddFieldDto request) { var command = request.ToCommand(parentId); var response = await InvokeCommandAsync(app, command); return CreatedAtAction(nameof(SchemasController.GetSchema), "Schemas", new { app, name }, response); } /// /// Configure UI fields. /// /// The name of the app. /// The name of the schema. /// The request that contains the field names. /// /// 200 => Schema UI fields defined. /// 400 => Schema field contains invalid field names. /// 404 => Schema or app not found. /// [HttpPut] [Route("apps/{app}/schemas/{name}/fields/ui/")] [ProducesResponseType(typeof(SchemaDetailsDto), 200)] [ApiPermission(Permissions.AppSchemasUpdate)] [ApiCosts(1)] public async Task PutSchemaUIFields(string app, string name, [FromBody] ConfigureUIFieldsDto request) { var command = request.ToCommand(); var response = await InvokeCommandAsync(app, command); return Ok(response); } /// /// Reorders the fields. /// /// The name of the app. /// The name of the schema. /// The request that contains the field ids. /// /// 200 => Schema fields reordered. /// 400 => Schema field ids do not cover the fields of the schema. /// 404 => Schema or app not found. /// [HttpPut] [Route("apps/{app}/schemas/{name}/fields/ordering/")] [ProducesResponseType(typeof(SchemaDetailsDto), 200)] [ApiPermission(Permissions.AppSchemasUpdate)] [ApiCosts(1)] public async Task PutSchemaFieldOrdering(string app, string name, [FromBody] ReorderFieldsDto request) { var command = request.ToCommand(); var response = await InvokeCommandAsync(app, command); return Ok(response); } /// /// Reorders the nested fields. /// /// The name of the app. /// The name of the schema. /// The parent field id. /// The request that contains the field ids. /// /// 200 => Schema fields reordered. /// 400 => Schema field ids do not cover the fields of the schema. /// 404 => Schema, field or app not found. /// [HttpPut] [Route("apps/{app}/schemas/{name}/fields/{parentId:long}/nested/ordering/")] [ProducesResponseType(typeof(SchemaDetailsDto), 200)] [ApiPermission(Permissions.AppSchemasUpdate)] [ApiCosts(1)] public async Task PutNestedFieldOrdering(string app, string name, long parentId, [FromBody] ReorderFieldsDto request) { var command = request.ToCommand(parentId); var response = await InvokeCommandAsync(app, command); return Ok(response); } /// /// Update a schema field. /// /// The name of the app. /// The name of the schema. /// The id of the field to update. /// The field object that needs to be added to the schema. /// /// 200 => Schema field updated. /// 400 => Schema field properties not valid or field is locked. /// 404 => Schema, field or app not found. /// [HttpPut] [Route("apps/{app}/schemas/{name}/fields/{id:long}/")] [ProducesResponseType(typeof(SchemaDetailsDto), 200)] [ApiPermission(Permissions.AppSchemasUpdate)] [ApiCosts(1)] public async Task PutField(string app, string name, long id, [FromBody] UpdateFieldDto request) { var command = request.ToCommand(id); var response = await InvokeCommandAsync(app, command); return Ok(response); } /// /// Update a nested schema field. /// /// The name of the app. /// The name of the schema. /// The parent field id. /// The id of the field to update. /// The field object that needs to be added to the schema. /// /// 200 => Schema field updated. /// 400 => Schema field properties not valid or field is locked. /// 404 => Schema, field or app not found. /// [HttpPut] [Route("apps/{app}/schemas/{name}/fields/{parentId:long}/nested/{id:long}/")] [ProducesResponseType(typeof(SchemaDetailsDto), 200)] [ApiPermission(Permissions.AppSchemasUpdate)] [ApiCosts(1)] public async Task PutNestedField(string app, string name, long parentId, long id, [FromBody] UpdateFieldDto request) { var command = request.ToCommand(id, parentId); var response = await InvokeCommandAsync(app, command); return Ok(response); } /// /// Lock a schema field. /// /// The name of the app. /// The name of the schema. /// The id of the field to lock. /// /// 200 => Schema field shown. /// 400 => Schema field already locked. /// 404 => Schema, field or app not found. /// /// /// A locked field cannot be updated or deleted. /// [HttpPut] [Route("apps/{app}/schemas/{name}/fields/{id:long}/lock/")] [ProducesResponseType(typeof(SchemaDetailsDto), 200)] [ApiPermission(Permissions.AppSchemasUpdate)] [ApiCosts(1)] public async Task LockField(string app, string name, long id) { var command = new LockField { FieldId = id }; var response = await InvokeCommandAsync(app, command); return Ok(response); } /// /// Lock a nested schema field. /// /// The name of the app. /// The name of the schema. /// The parent field id. /// The id of the field to lock. /// /// 200 => Schema field hidden. /// 400 => Schema field already hidden. /// 404 => Field, schema, or app not found. /// /// /// A locked field cannot be edited or deleted. /// [HttpPut] [Route("apps/{app}/schemas/{name}/fields/{parentId:long}/nested/{id:long}/lock/")] [ProducesResponseType(typeof(SchemaDetailsDto), 200)] [ApiPermission(Permissions.AppSchemasUpdate)] [ApiCosts(1)] public async Task LockNestedField(string app, string name, long parentId, long id) { var command = new LockField { ParentFieldId = parentId, FieldId = id }; var response = await InvokeCommandAsync(app, command); return Ok(response); } /// /// Hide a schema field. /// /// The name of the app. /// The name of the schema. /// The id of the field to hide. /// /// 200 => Schema field hidden. /// 400 => Schema field already hidden. /// 404 => Schema, field or app not found. /// /// /// A hidden field is not part of the API response, but can still be edited in the portal. /// [HttpPut] [Route("apps/{app}/schemas/{name}/fields/{id:long}/hide/")] [ProducesResponseType(typeof(SchemaDetailsDto), 200)] [ApiPermission(Permissions.AppSchemasUpdate)] [ApiCosts(1)] public async Task HideField(string app, string name, long id) { var command = new HideField { FieldId = id }; var response = await InvokeCommandAsync(app, command); return Ok(response); } /// /// Hide a nested schema field. /// /// The name of the app. /// The name of the schema. /// The parent field id. /// The id of the field to hide. /// /// 200 => Schema field hidden. /// 400 => Schema field already hidden. /// 404 => Field, schema, or app not found. /// /// /// A hidden field is not part of the API response, but can still be edited in the portal. /// [HttpPut] [Route("apps/{app}/schemas/{name}/fields/{parentId:long}/nested/{id:long}/hide/")] [ProducesResponseType(typeof(SchemaDetailsDto), 200)] [ApiPermission(Permissions.AppSchemasUpdate)] [ApiCosts(1)] public async Task HideNestedField(string app, string name, long parentId, long id) { var command = new HideField { ParentFieldId = parentId, FieldId = id }; var response = await InvokeCommandAsync(app, command); return Ok(response); } /// /// Show a schema field. /// /// The name of the app. /// The name of the schema. /// The id of the field to show. /// /// 200 => Schema field shown. /// 400 => Schema field already visible. /// 404 => Schema, field or app not found. /// /// /// A hidden field is not part of the API response, but can still be edited in the portal. /// [HttpPut] [Route("apps/{app}/schemas/{name}/fields/{id:long}/show/")] [ProducesResponseType(typeof(SchemaDetailsDto), 200)] [ApiPermission(Permissions.AppSchemasUpdate)] [ApiCosts(1)] public async Task ShowField(string app, string name, long id) { var command = new ShowField { FieldId = id }; var response = await InvokeCommandAsync(app, command); return Ok(response); } /// /// Show a nested schema field. /// /// The name of the app. /// The name of the schema. /// The parent field id. /// The id of the field to show. /// /// 200 => Schema field shown. /// 400 => Schema field already visible. /// 404 => Schema, field or app not found. /// /// /// A hidden field is not part of the API response, but can still be edited in the portal. /// [HttpPut] [Route("apps/{app}/schemas/{name}/fields/{parentId:long}/nested/{id:long}/show/")] [ProducesResponseType(typeof(SchemaDetailsDto), 200)] [ApiPermission(Permissions.AppSchemasUpdate)] [ApiCosts(1)] public async Task ShowNestedField(string app, string name, long parentId, long id) { var command = new ShowField { ParentFieldId = parentId, FieldId = id }; var response = await InvokeCommandAsync(app, command); return Ok(response); } /// /// Enable a schema field. /// /// The name of the app. /// The name of the schema. /// The id of the field to enable. /// /// 200 => Schema field enabled. /// 400 => Schema field already enabled. /// 404 => Schema, field or app not found. /// /// /// A disabled field cannot not be edited in the squidex portal anymore, but will be part of the API response. /// [HttpPut] [Route("apps/{app}/schemas/{name}/fields/{id:long}/enable/")] [ProducesResponseType(typeof(SchemaDetailsDto), 200)] [ApiPermission(Permissions.AppSchemasUpdate)] [ApiCosts(1)] public async Task EnableField(string app, string name, long id) { var command = new EnableField { FieldId = id }; var response = await InvokeCommandAsync(app, command); return Ok(response); } /// /// Enable a nested schema field. /// /// The name of the app. /// The name of the schema. /// The parent field id. /// The id of the field to enable. /// /// 200 => Schema field enabled. /// 400 => Schema field already enabled. /// 404 => Schema, field or app not found. /// /// /// A disabled field cannot not be edited in the squidex portal anymore, but will be part of the API response. /// [HttpPut] [Route("apps/{app}/schemas/{name}/fields/{parentId:long}/nested/{id:long}/enable/")] [ProducesResponseType(typeof(SchemaDetailsDto), 200)] [ApiPermission(Permissions.AppSchemasUpdate)] [ApiCosts(1)] public async Task EnableNestedField(string app, string name, long parentId, long id) { var command = new EnableField { ParentFieldId = parentId, FieldId = id }; var response = await InvokeCommandAsync(app, command); return Ok(response); } /// /// Disable a schema field. /// /// The name of the app. /// The name of the schema. /// The id of the field to disable. /// /// 200 => Schema field disabled. /// 400 => Schema field already disabled. /// 404 => Schema, field or app not found. /// /// /// A disabled field cannot not be edited in the squidex portal anymore, but will be part of the API response. /// [HttpPut] [Route("apps/{app}/schemas/{name}/fields/{id:long}/disable/")] [ProducesResponseType(typeof(SchemaDetailsDto), 200)] [ApiPermission(Permissions.AppSchemasUpdate)] [ApiCosts(1)] public async Task DisableField(string app, string name, long id) { var command = new DisableField { FieldId = id }; var response = await InvokeCommandAsync(app, command); return Ok(response); } /// /// Disable nested a schema field. /// /// The name of the app. /// The name of the schema. /// The parent field id. /// The id of the field to disable. /// /// 200 => Schema field disabled. /// 400 => Schema field already disabled. /// 404 => Schema, field or app not found. /// /// /// A disabled field cannot not be edited in the squidex portal anymore, but will be part of the API response. /// [HttpPut] [Route("apps/{app}/schemas/{name}/fields/{parentId:long}/nested/{id:long}/disable/")] [ProducesResponseType(typeof(SchemaDetailsDto), 200)] [ApiPermission(Permissions.AppSchemasUpdate)] [ApiCosts(1)] public async Task DisableNestedField(string app, string name, long parentId, long id) { var command = new DisableField { ParentFieldId = parentId, FieldId = id }; var response = await InvokeCommandAsync(app, command); return Ok(response); } /// /// Delete a schema field. /// /// The name of the app. /// The name of the schema. /// The id of the field to disable. /// /// 200 => Schema field deleted. /// 400 => Field is locked. /// 404 => Schema, field or app not found. /// [HttpDelete] [Route("apps/{app}/schemas/{name}/fields/{id:long}/")] [ProducesResponseType(typeof(SchemaDetailsDto), 200)] [ApiPermission(Permissions.AppSchemasUpdate)] [ApiCosts(1)] public async Task DeleteField(string app, string name, long id) { var command = new DeleteField { FieldId = id }; var response = await InvokeCommandAsync(app, command); return Ok(response); } /// /// Delete a nested schema field. /// /// The name of the app. /// The name of the schema. /// The parent field id. /// The id of the field to disable. /// /// 200 => Schema field deleted. /// 400 => Field is locked. /// 404 => Schema, field or app not found. /// [HttpDelete] [Route("apps/{app}/schemas/{name}/fields/{parentId:long}/nested/{id:long}/")] [ProducesResponseType(typeof(SchemaDetailsDto), 200)] [ApiPermission(Permissions.AppSchemasUpdate)] [ApiCosts(1)] public async Task DeleteNestedField(string app, string name, long parentId, long id) { var command = new DeleteField { ParentFieldId = parentId, FieldId = id }; var response = await InvokeCommandAsync(app, command); return Ok(response); } private async Task InvokeCommandAsync(string app, ICommand command) { var context = await CommandBus.PublishAsync(command); var result = context.Result(); var response = SchemaDetailsDto.FromSchemaWithDetails(result, this, app); return response; } } }