using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using API.Constants;
using API.Data;
using API.Data.Repositories;
using API.DTOs.Dashboard;
using API.DTOs.Filtering.v2;
using API.Entities;
using API.Extensions;
using API.Helpers;
using API.Services;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
namespace API.Controllers;
#nullable enable
///
/// This is responsible for Filter caching
///
public class FilterController : BaseApiController
{
private readonly IUnitOfWork _unitOfWork;
private readonly ILocalizationService _localizationService;
private readonly IStreamService _streamService;
private readonly ILogger _logger;
public FilterController(IUnitOfWork unitOfWork, ILocalizationService localizationService, IStreamService streamService,
ILogger logger)
{
_unitOfWork = unitOfWork;
_localizationService = localizationService;
_streamService = streamService;
_logger = logger;
}
///
/// Creates or Updates the filter
///
///
///
[HttpPost("update")]
public async Task CreateOrUpdateSmartFilter(FilterV2Dto dto)
{
var user = await _unitOfWork.UserRepository.GetUserByIdAsync(User.GetUserId(), AppUserIncludes.SmartFilters);
if (user == null) return Unauthorized();
if (User.IsInRole(PolicyConstants.ReadOnlyRole)) return BadRequest(await _localizationService.Translate(User.GetUserId(), "permission-denied"));
if (string.IsNullOrWhiteSpace(dto.Name)) return BadRequest("Name must be set");
if (Seed.DefaultStreams.Any(s => s.Name.Equals(dto.Name, StringComparison.InvariantCultureIgnoreCase)))
{
return BadRequest("You cannot use the name of a system provided stream");
}
var existingFilter =
user.SmartFilters.FirstOrDefault(f => f.Name.Equals(dto.Name, StringComparison.InvariantCultureIgnoreCase));
if (existingFilter != null)
{
// Update the filter
existingFilter.Filter = SmartFilterHelper.Encode(dto);
_unitOfWork.AppUserSmartFilterRepository.Update(existingFilter);
}
else
{
existingFilter = new AppUserSmartFilter()
{
Name = dto.Name,
Filter = SmartFilterHelper.Encode(dto)
};
user.SmartFilters.Add(existingFilter);
_unitOfWork.UserRepository.Update(user);
}
if (!_unitOfWork.HasChanges()) return Ok();
await _unitOfWork.CommitAsync();
return Ok();
}
[HttpGet]
public ActionResult> GetFilters()
{
return Ok(_unitOfWork.AppUserSmartFilterRepository.GetAllDtosByUserId(User.GetUserId()));
}
[HttpDelete]
public async Task DeleteFilter(int filterId)
{
if (User.IsInRole(PolicyConstants.ReadOnlyRole)) return BadRequest(await _localizationService.Translate(User.GetUserId(), "permission-denied"));
var filter = await _unitOfWork.AppUserSmartFilterRepository.GetById(filterId);
if (filter == null) return Ok();
// This needs to delete any dashboard filters that have it too
var streams = await _unitOfWork.UserRepository.GetDashboardStreamWithFilter(filter.Id);
_unitOfWork.UserRepository.Delete(streams);
var streams2 = await _unitOfWork.UserRepository.GetSideNavStreamWithFilter(filter.Id);
_unitOfWork.UserRepository.Delete(streams2);
_unitOfWork.AppUserSmartFilterRepository.Delete(filter);
await _unitOfWork.CommitAsync();
return Ok();
}
///
/// Encode the Filter
///
///
///
[HttpPost("encode")]
public ActionResult EncodeFilter(FilterV2Dto dto)
{
return Ok(SmartFilterHelper.Encode(dto));
}
///
/// Decodes the Filter
///
///
///
[HttpPost("decode")]
public ActionResult DecodeFilter(DecodeFilterDto dto)
{
return Ok(SmartFilterHelper.Decode(dto.EncodedFilter));
}
///
/// Rename a Smart Filter given the filterId and new name
///
///
///
///
[HttpPost("rename")]
public async Task RenameFilter([FromQuery] int filterId, [FromQuery] string name)
{
try
{
var user = await _unitOfWork.UserRepository.GetUserByIdAsync(User.GetUserId(),
AppUserIncludes.SmartFilters);
if (user == null) return Unauthorized();
name = name.Trim();
if (User.IsInRole(PolicyConstants.ReadOnlyRole))
{
return BadRequest(await _localizationService.Translate(user.Id, "permission-denied"));
}
if (string.IsNullOrWhiteSpace(name))
{
return BadRequest(await _localizationService.Translate(user.Id, "smart-filter-name-required"));
}
if (Seed.DefaultStreams.Any(s => s.Name.Equals(name, StringComparison.InvariantCultureIgnoreCase)))
{
return BadRequest(await _localizationService.Translate(user.Id, "smart-filter-system-name"));
}
var filter = user.SmartFilters.FirstOrDefault(f => f.Id == filterId);
if (filter == null)
{
return BadRequest(await _localizationService.Translate(user.Id, "filter-not-found"));
}
filter.Name = name;
_unitOfWork.AppUserSmartFilterRepository.Update(filter);
await _unitOfWork.CommitAsync();
await _streamService.RenameSmartFilterStreams(filter);
return Ok();
}
catch (Exception ex)
{
_logger.LogError(ex, "There was an exception when renaming smart filter: {FilterId}", filterId);
return BadRequest(await _localizationService.Translate(User.GetUserId(), "generic-error"));
}
}
}