175 lines
5.4 KiB
C#
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();
|
|
}
|
|
} |