Implemented user-customizable, persistent grid and band layouts for CatalogsGrid and MassDataGrid. Added backend API, database entity, and repository for storing layouts per user. Refactored grids to support dynamic band/column rendering, layout management UI, and per-user storage via localStorage and the new API. Registered all necessary services and updated data context. Enables flexible, user-specific grid experiences with saved layouts.
95 lines
3.2 KiB
C#
95 lines
3.2 KiB
C#
using System.Text;
|
|
using DbFirst.Application.Repositories;
|
|
using DbFirst.Domain.Entities;
|
|
using Microsoft.AspNetCore.Mvc;
|
|
|
|
namespace DbFirst.API.Controllers;
|
|
|
|
[ApiController]
|
|
[Route("api/[controller]")]
|
|
public class LayoutsController : ControllerBase
|
|
{
|
|
private readonly ILayoutRepository _repository;
|
|
|
|
public LayoutsController(ILayoutRepository repository)
|
|
{
|
|
_repository = repository;
|
|
}
|
|
|
|
[HttpGet]
|
|
public async Task<ActionResult<LayoutDto>> Get([FromQuery] string layoutType, [FromQuery] string layoutKey, [FromQuery] string userName, CancellationToken cancellationToken)
|
|
{
|
|
if (string.IsNullOrWhiteSpace(layoutType) || string.IsNullOrWhiteSpace(layoutKey) || string.IsNullOrWhiteSpace(userName))
|
|
{
|
|
return BadRequest("layoutType, layoutKey und userName sind erforderlich.");
|
|
}
|
|
|
|
var entity = await _repository.GetAsync(layoutType, layoutKey, userName, cancellationToken);
|
|
if (entity == null)
|
|
{
|
|
return NotFound();
|
|
}
|
|
|
|
return Ok(Map(entity));
|
|
}
|
|
|
|
[HttpPost]
|
|
public async Task<ActionResult<LayoutDto>> Upsert(LayoutDto dto, CancellationToken cancellationToken)
|
|
{
|
|
if (string.IsNullOrWhiteSpace(dto.LayoutType) || string.IsNullOrWhiteSpace(dto.LayoutKey) || string.IsNullOrWhiteSpace(dto.UserName))
|
|
{
|
|
return BadRequest("LayoutType, LayoutKey und UserName sind erforderlich.");
|
|
}
|
|
|
|
var data = string.IsNullOrWhiteSpace(dto.LayoutData)
|
|
? Array.Empty<byte>()
|
|
: Encoding.UTF8.GetBytes(dto.LayoutData);
|
|
|
|
try
|
|
{
|
|
var entity = await _repository.UpsertAsync(dto.LayoutType, dto.LayoutKey, dto.UserName, data, cancellationToken);
|
|
return Ok(Map(entity));
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
var detail = ex.InnerException?.Message ?? ex.Message;
|
|
return Problem(detail: detail, statusCode: StatusCodes.Status500InternalServerError);
|
|
}
|
|
}
|
|
|
|
[HttpDelete]
|
|
public async Task<IActionResult> Delete([FromQuery] string layoutType, [FromQuery] string layoutKey, [FromQuery] string userName, CancellationToken cancellationToken)
|
|
{
|
|
if (string.IsNullOrWhiteSpace(layoutType) || string.IsNullOrWhiteSpace(layoutKey) || string.IsNullOrWhiteSpace(userName))
|
|
{
|
|
return BadRequest("layoutType, layoutKey und userName sind erforderlich.");
|
|
}
|
|
|
|
var deleted = await _repository.DeleteAsync(layoutType, layoutKey, userName, cancellationToken);
|
|
return deleted ? NoContent() : NotFound();
|
|
}
|
|
|
|
private static LayoutDto Map(SmfLayout entity)
|
|
{
|
|
var layoutData = entity.LayoutData.Length == 0
|
|
? string.Empty
|
|
: Encoding.UTF8.GetString(entity.LayoutData);
|
|
|
|
return new LayoutDto
|
|
{
|
|
LayoutType = entity.LayoutType,
|
|
LayoutKey = entity.LayoutKey,
|
|
UserName = entity.UserName,
|
|
LayoutData = layoutData
|
|
};
|
|
}
|
|
|
|
public sealed class LayoutDto
|
|
{
|
|
public string LayoutType { get; set; } = string.Empty;
|
|
public string LayoutKey { get; set; } = string.Empty;
|
|
public string UserName { get; set; } = string.Empty;
|
|
public string LayoutData { get; set; } = string.Empty;
|
|
}
|
|
}
|