User
fix: adjust overall structure, clean out unnecessary fields, adjust table columns and layouts on task list and issue list
ecb51fa
Raw
History Blame Contribute Delete
6.27 kB
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using TaskTrackingSystem.Database.AppDbContextModels;
using TaskTrackingSystem.Shared;
using TaskTrackingSystem.Shared.Enums;
using TaskTrackingSystem.Shared.Models.Dashboard;
using TaskTrackingSystem.WebApi.Infrastructure;
namespace TaskTrackingSystem.WebApi.Features.Dashboard
{
public class DashboardService
{
private readonly AppDbContext _db;
public DashboardService(AppDbContext db)
{
_db = db;
}
public async Task<Result<DashboardSummaryDto>> GetSummaryAsync(long roleId, long currentUserId)
{
var isAdmin = await DataScopeAuthorization.IsAdminScopeAsync(_db, roleId);
var isManager = await DataScopeAuthorization.IsManagerScopeAsync(_db, roleId);
var projects = BuildAccessibleProjectQuery(isAdmin, currentUserId);
var tasks = BuildAccessibleTaskQuery(isAdmin, isManager, currentUserId);
var totalUsers = isAdmin
? await _db.Users.CountAsync(u => !u.IsDeleted)
: await _db.Users
.Where(u => !u.IsDeleted &&
projects.SelectMany(p => p.ProjectMembers.Select(pm => pm.UserId))
.Distinct()
.Contains(u.Id))
.CountAsync();
var activeProjectsCount = await projects.CountAsync();
var pendingTasksCount = await tasks.CountAsync(t => t.StatusId != AppTaskStatus.Done);
var summary = new DashboardSummaryDto
{
TotalUsers = totalUsers,
ActiveProjectsCount = activeProjectsCount,
PendingTasksCount = pendingTasksCount
};
return Result<DashboardSummaryDto>.Success(summary);
}
public async Task<Result<IEnumerable<TaskStatusOverviewDto>>> GetTasksOverviewAsync(long roleId, long currentUserId)
{
var isAdmin = await DataScopeAuthorization.IsAdminScopeAsync(_db, roleId);
var isManager = await DataScopeAuthorization.IsManagerScopeAsync(_db, roleId);
var groupedTasks = await BuildAccessibleTaskQuery(isAdmin, isManager, currentUserId)
.GroupBy(t => t.StatusId)
.Select(g => new
{
StatusId = g.Key,
Count = g.Count()
})
.ToListAsync();
var statusMap = new Dictionary<AppTaskStatus, string>
{
{ AppTaskStatus.Todo, "To Do" },
{ AppTaskStatus.InProgress, "In Progress" },
{ AppTaskStatus.Done, "Done" }
};
var overview = groupedTasks.Select(gt => new TaskStatusOverviewDto
{
StatusId = gt.StatusId,
StatusName = statusMap.TryGetValue(gt.StatusId, out var name) ? name : $"Status {gt.StatusId}",
TaskCount = gt.Count
}).ToList();
foreach (var status in statusMap)
{
if (!overview.Any(o => o.StatusId == status.Key))
{
overview.Add(new TaskStatusOverviewDto
{
StatusId = status.Key,
StatusName = status.Value,
TaskCount = 0
});
}
}
return Result<IEnumerable<TaskStatusOverviewDto>>.Success(overview.OrderBy(o => o.StatusId));
}
public async Task<Result<IEnumerable<ProjectProgressDto>>> GetProjectProgressAsync(long roleId, long currentUserId)
{
var isAdmin = await DataScopeAuthorization.IsAdminScopeAsync(_db, roleId);
var activeProjects = await BuildAccessibleProjectQuery(isAdmin, currentUserId).ToListAsync();
var progressList = new List<ProjectProgressDto>();
foreach (var project in activeProjects)
{
var tasks = await _db.Tasks
.Where(t => t.ProjectId == project.Id && t.IsDeleted != true && !t.IsArchived)
.ToListAsync();
int totalTasks = tasks.Count;
int completedTasks = tasks.Count(t => t.StatusId == AppTaskStatus.Done);
double percentage = totalTasks > 0 ? Math.Round(((double)completedTasks / totalTasks) * 100, 2) : 0;
progressList.Add(new ProjectProgressDto
{
ProjectId = project.Id,
ProjectName = project.Name,
TotalTasksCount = totalTasks,
CompletedTasksCount = completedTasks,
CompletionPercentage = percentage
});
}
return Result<IEnumerable<ProjectProgressDto>>.Success(progressList);
}
private IQueryable<TaskTrackingSystem.Database.AppDbContextModels.Task> BuildAccessibleTaskQuery(bool isAdmin, bool isManager, long currentUserId)
{
var query = _db.Tasks.Where(t => t.IsDeleted != true && !t.IsArchived);
if (isAdmin)
{
return query;
}
if (isManager)
{
return query.Where(t =>
t.AssignedTo == currentUserId ||
t.CreatedBy == currentUserId ||
t.Project.ProjectMembers.Any(pm => pm.UserId == currentUserId));
}
return query.Where(t =>
t.AssignedTo == currentUserId ||
t.CreatedBy == currentUserId);
}
private IQueryable<TaskTrackingSystem.Database.AppDbContextModels.Project> BuildAccessibleProjectQuery(bool isAdmin, long currentUserId)
{
var query = _db.Projects.Where(p => p.IsDeleted != true);
if (isAdmin)
{
return query;
}
return query.Where(p =>
p.CreatedById == currentUserId ||
p.ProjectMembers.Any(pm => pm.UserId == currentUserId));
}
}
}