Spaces:
Running
Running
User
fix: adjust overall structure, clean out unnecessary fields, adjust table columns and layouts on task list and issue list
ecb51fa | 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)); | |
| } | |
| } | |
| } | |