Files
MilkyShots/Lactose/Controllers/TagController.cs

175 lines
5.4 KiB
C#

using Butter.Dtos;
using Butter.Dtos.Tag;
using Lactose.Mapper;
using Lactose.Models;
using Lactose.Repositories;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Infrastructure;
namespace Lactose.Controllers;
//TODO: logging
[Authorize]
[ApiController]
[Route("api/[controller]")]
public class TagController(
//TODO: add logging
//ILogger<TagController> logger,
ITagRepository tagRepository
) : ControllerBase {
[HttpGet("{id}")]
public ActionResult<TagDto> Get(Guid id, bool children = false, bool ancestors = false) {
Tag? tag = tagRepository.Find(id);
if (tag == null) { return NotFound(); }
var tagDto = TagsMapper.ToTagDto(tag);
tagDto.Parent = tag.Parent == null ? null : TagsMapper.ToTagDto(tag.Parent);
if (children) {
tagDto.Children = [];
tagRepository.GetChildren(tag.Id).ForEach(t => tagDto.Children.Add(TagsMapper.ToTagDto(t)));
}
//TODO: Protect from overflow
if (ancestors) {
Tag? index = tag.Parent;
TagDto? indexDto = tagDto;
List<Tag> ancestorsTags = [];
// This is redundant, because circular references shouldn't be present
while (index != null && !ancestorsTags.Contains(tag)) {
ancestorsTags.Add(index);
indexDto.Parent = TagsMapper.ToTagDto(index);
index = index.Parent;
indexDto = indexDto.Parent;
}
}
return tagDto;
}
[HttpGet]
public ActionResult<List<TagDto>> GetAll(PagedSearchParametersDto pagedSearch) {
pagedSearch.Search ??= string.Empty;
if(pagedSearch.Page < 0) { return BadRequest("Page must be greater than 0"); }
if(pagedSearch.PageSize < 0) { return BadRequest("PageSize must be greater than 0"); }
List<Tag> tags = tagRepository.Search(pagedSearch.Search, pagedSearch.Page, pagedSearch.PageSize);
List<TagDto> tagsDto = [];
tags.ForEach(
t => {
var tagDto = TagsMapper.ToTagDto(t);
tagDto.Parent = t.Parent == null ? null : TagsMapper.ToTagDto(t.Parent);
tagsDto.Add(tagDto);
}
);
return tagsDto;
}
[Authorize(Roles = "Admin, Curator")]
[HttpPost("{id}")]
public IStatusCodeActionResult Update([FromRoute] Guid id, [FromBody] TagUpdateDto tagDto) {
IStatusCodeActionResult result = UpdateTag(id, tagDto.Name, tagDto.Parent);
if (result.StatusCode == StatusCodes.Status200OK) { tagRepository.Save(); }
return result;
}
[Authorize(Roles = "Admin, Curator")]
[HttpPost]
public IStatusCodeActionResult BulkUpdate([FromBody] BulkDto<TagUpdateDto> tagBulkDto) {
foreach (Guid id in tagBulkDto.Ids) {
IStatusCodeActionResult result = UpdateTag(id, tagBulkDto.Data.Name, tagBulkDto.Data.Parent);
if (result.StatusCode != StatusCodes.Status200OK) { return result; }
}
tagRepository.Save();
return Ok();
}
[Authorize(Roles = "Admin, Curator")]
[HttpDelete("{id}")]
public ActionResult Delete([FromRoute] Guid id) {
IStatusCodeActionResult result = DeleteTag(id);
if (result.StatusCode == StatusCodes.Status200OK) { tagRepository.Save(); }
return (ActionResult)result;
}
[Authorize(Roles = "Admin, Curator")]
[HttpDelete]
public IActionResult BulkDelete([FromBody] List<Guid> ids) {
foreach (Guid id in ids) {
IStatusCodeActionResult result = DeleteTag(id);
if (result.StatusCode != StatusCodes.Status200OK) { return result; }
}
tagRepository.Save();
return Ok();
}
[Authorize(Roles = "Admin, Curator")]
[HttpPut]
public ActionResult Create([FromBody] TagCreateDto tagDto) {
if (tagRepository.FindByName(tagDto.Name) != null) { return Conflict($"Tag with name {tagDto.Name} already exist"); }
var tag = new Tag() {
Name = tagDto.Name
};
if (tagDto.Parent != null && tagRepository.Find(tagDto.Parent.Value) == null) {
return BadRequest($"No Tag with id {tagDto.Parent} found");
}
tag.ParentId = tagDto.Parent;
tagRepository.Insert(tag);
tagRepository.Save();
return Ok();
}
IStatusCodeActionResult DeleteTag(Guid id) {
Tag? tag = tagRepository.Find(id);
if (tag == null) { return NotFound($"Tag {id} not found"); }
tagRepository.Delete(tag);
return Ok();
}
IStatusCodeActionResult UpdateTag(Guid id, string? name, Guid? parentId) {
Tag? tag = tagRepository.Find(id);
if (tag == null) { return NotFound($"Tag {id} not found"); }
if (name != null) {
Tag? foundTag = tagRepository.FindByName(name);
if (foundTag != null && foundTag.Id != tag.Id) { return Conflict($"Tag with name '{name}' already exists"); }
tag.Name = name;
}
if (parentId == null) { return Ok(); }
if (parentId.Value.Equals(Guid.Empty)) { tag.Parent = null; } else {
Tag? parent = tagRepository.Find(parentId.Value);
if (parent == null) { return NotFound($"Parent tag on {id} was not found"); }
tag.Parent = parent;
}
return Ok();
}
}