From 2f58c549ac1852d11759f1f78307aa6670a1413b Mon Sep 17 00:00:00 2001 From: Marcin Bator Date: Thu, 21 Nov 2024 11:34:01 +0100 Subject: [PATCH 1/2] feat: #57 basic sorting users mechanism --- .../Common/Model/SortDirection.cs | 6 ++++ .../AdministrationController.cs | 6 ++-- .../Administration/AdministrationService.cs | 30 ++++++++++++++++--- .../Administration/Dto/UserSortByFields.cs | 8 +++++ .../Test/Service/AdministrationServiceTest.cs | 3 +- rag-2-backend/appsettings.Development.json | 3 +- 6 files changed, 48 insertions(+), 8 deletions(-) create mode 100644 rag-2-backend/Infrastructure/Common/Model/SortDirection.cs create mode 100644 rag-2-backend/Infrastructure/Module/Administration/Dto/UserSortByFields.cs diff --git a/rag-2-backend/Infrastructure/Common/Model/SortDirection.cs b/rag-2-backend/Infrastructure/Common/Model/SortDirection.cs new file mode 100644 index 0000000..6ee5611 --- /dev/null +++ b/rag-2-backend/Infrastructure/Common/Model/SortDirection.cs @@ -0,0 +1,6 @@ +namespace rag_2_backend.Infrastructure.Common.Model; + +public enum SortDirection +{ + Asc, Desc +} \ No newline at end of file diff --git a/rag-2-backend/Infrastructure/Module/Administration/AdministrationController.cs b/rag-2-backend/Infrastructure/Module/Administration/AdministrationController.cs index c78c534..dec8669 100644 --- a/rag-2-backend/Infrastructure/Module/Administration/AdministrationController.cs +++ b/rag-2-backend/Infrastructure/Module/Administration/AdministrationController.cs @@ -64,8 +64,10 @@ public LimitsResponse GetCurrentLimits() /// Get all users list (Admin, Teacher) [HttpGet("users")] [Authorize(Roles = "Admin, Teacher")] - public List GetStudents() + public List GetUsers( + SortDirection sortDirection = SortDirection.Asc, UserSortByFields sortBy = UserSortByFields.Id + ) { - return administrationService.GetStudents(); + return administrationService.GetUsers(sortDirection, sortBy); } } \ No newline at end of file diff --git a/rag-2-backend/Infrastructure/Module/Administration/AdministrationService.cs b/rag-2-backend/Infrastructure/Module/Administration/AdministrationService.cs index 8563865..70783cb 100644 --- a/rag-2-backend/Infrastructure/Module/Administration/AdministrationService.cs +++ b/rag-2-backend/Infrastructure/Module/Administration/AdministrationService.cs @@ -1,10 +1,13 @@ #region +using System.Linq.Expressions; using HttpExceptions.Exceptions; +using Microsoft.EntityFrameworkCore; using rag_2_backend.Infrastructure.Common.Mapper; using rag_2_backend.Infrastructure.Common.Model; using rag_2_backend.Infrastructure.Dao; using rag_2_backend.Infrastructure.Database; +using rag_2_backend.Infrastructure.Module.Administration.Dto; using rag_2_backend.Infrastructure.Module.User.Dto; #endregion @@ -45,10 +48,29 @@ public UserResponse GetUserDetails(string principalEmail, int userId) return UserMapper.Map(userDao.GetUserByIdOrThrow(userId)); } - public List GetStudents() + public List GetUsers(SortDirection sortDirection, UserSortByFields sortBy) { - return context.Users - .Select(u => UserMapper.Map(u)) - .ToList(); + var query = context.Users.Include(u=>u.Course).AsQueryable(); + + query = sortBy switch + { + UserSortByFields.Id => ApplySorting(query, x => x.Id, sortDirection), + UserSortByFields.Email => ApplySorting(query, x => x.Email, sortDirection), + UserSortByFields.Name => ApplySorting(query, x => x.Name, sortDirection), + UserSortByFields.StudyYearCycleA => ApplySorting(query, x => x.StudyCycleYearA, sortDirection), + UserSortByFields.StudyYearCycleB => ApplySorting(query, x => x.StudyCycleYearB, sortDirection), + UserSortByFields.LastPlayed => ApplySorting(query, x => x.LastPlayed, sortDirection), + UserSortByFields.CourseName => ApplySorting(query, x=>x.Course != null ? x.Course.Name : string.Empty, sortDirection), + UserSortByFields.Group => ApplySorting(query, x => x.Group, sortDirection), + _ => query + }; + + return query.AsEnumerable().Select(UserMapper.Map).ToList(); + } + + private static IQueryable ApplySorting(IQueryable query, Expression> keySelector, SortDirection sortDirection) + { + return sortDirection == SortDirection.Desc ? query.OrderByDescending(keySelector) : query.OrderBy(keySelector); } + } \ No newline at end of file diff --git a/rag-2-backend/Infrastructure/Module/Administration/Dto/UserSortByFields.cs b/rag-2-backend/Infrastructure/Module/Administration/Dto/UserSortByFields.cs new file mode 100644 index 0000000..1f3b043 --- /dev/null +++ b/rag-2-backend/Infrastructure/Module/Administration/Dto/UserSortByFields.cs @@ -0,0 +1,8 @@ +using System.Text.RegularExpressions; + +namespace rag_2_backend.Infrastructure.Module.Administration.Dto; + +public enum UserSortByFields +{ + Id, Email, Name, StudyYearCycleA, StudyYearCycleB, LastPlayed, CourseName, Group +} \ No newline at end of file diff --git a/rag-2-backend/Test/Service/AdministrationServiceTest.cs b/rag-2-backend/Test/Service/AdministrationServiceTest.cs index bf740af..5ef638d 100644 --- a/rag-2-backend/Test/Service/AdministrationServiceTest.cs +++ b/rag-2-backend/Test/Service/AdministrationServiceTest.cs @@ -10,6 +10,7 @@ using rag_2_backend.Infrastructure.Database; using rag_2_backend.Infrastructure.Database.Entity; using rag_2_backend.Infrastructure.Module.Administration; +using rag_2_backend.Infrastructure.Module.Administration.Dto; using rag_2_backend.Infrastructure.Module.User.Dto; using Xunit; @@ -116,7 +117,7 @@ public void ShouldGetStudents() Assert.Equal( JsonConvert.SerializeObject(response), - JsonConvert.SerializeObject(_administrationService.GetStudents()[0]) + JsonConvert.SerializeObject(_administrationService.GetUsers(SortDirection.Asc, UserSortByFields.Id)[0]) ); } } \ No newline at end of file diff --git a/rag-2-backend/appsettings.Development.json b/rag-2-backend/appsettings.Development.json index 0df88ac..8259ad1 100644 --- a/rag-2-backend/appsettings.Development.json +++ b/rag-2-backend/appsettings.Development.json @@ -7,7 +7,8 @@ }, "AllowedOrigins": "http://localhost:4200,http://localhost", "Jwt": { - "Key": "MIHcAgEBBEIBIHk9RDBDHoudslGHKpNqh8Tsr7fWu0J" + "Key": "MIHcAgEBBEIBIHk9RDBDHoudslGHKpNqh8Tsr7fWu0J", + "ExpireMinutes": 100 }, "ConnectionStrings": { "DefaultConnection": "Host=localhost;Port=5432;Database=postgres;Username=postgres;Password=postgres" From 0587434c60e57c0da0774255e277470b72025da4 Mon Sep 17 00:00:00 2001 From: Marcin Bator Date: Thu, 21 Nov 2024 12:03:56 +0100 Subject: [PATCH 2/2] feat: #57 filters for users --- .../Common/Model/SortDirection.cs | 3 +- .../AdministrationController.cs | 18 ++++++- .../Administration/AdministrationService.cs | 53 ++++++++++++++++--- .../Administration/Dto/UserSortByFields.cs | 11 ++-- .../Test/Service/AdministrationServiceTest.cs | 3 +- 5 files changed, 73 insertions(+), 15 deletions(-) diff --git a/rag-2-backend/Infrastructure/Common/Model/SortDirection.cs b/rag-2-backend/Infrastructure/Common/Model/SortDirection.cs index 6ee5611..6d6ce59 100644 --- a/rag-2-backend/Infrastructure/Common/Model/SortDirection.cs +++ b/rag-2-backend/Infrastructure/Common/Model/SortDirection.cs @@ -2,5 +2,6 @@ namespace rag_2_backend.Infrastructure.Common.Model; public enum SortDirection { - Asc, Desc + Asc, + Desc } \ No newline at end of file diff --git a/rag-2-backend/Infrastructure/Module/Administration/AdministrationController.cs b/rag-2-backend/Infrastructure/Module/Administration/AdministrationController.cs index dec8669..39f70f2 100644 --- a/rag-2-backend/Infrastructure/Module/Administration/AdministrationController.cs +++ b/rag-2-backend/Infrastructure/Module/Administration/AdministrationController.cs @@ -65,9 +65,23 @@ public LimitsResponse GetCurrentLimits() [HttpGet("users")] [Authorize(Roles = "Admin, Teacher")] public List GetUsers( - SortDirection sortDirection = SortDirection.Asc, UserSortByFields sortBy = UserSortByFields.Id + string? email, + int? studyCycleYearA, + int? studyCycleYearB, + string? group, + string? courseName, + SortDirection sortDirection = SortDirection.Asc, + UserSortByFields sortBy = UserSortByFields.Id ) { - return administrationService.GetUsers(sortDirection, sortBy); + return administrationService.GetUsers( + email, + studyCycleYearA, + studyCycleYearB, + group, + courseName, + sortDirection, + sortBy + ); } } \ No newline at end of file diff --git a/rag-2-backend/Infrastructure/Module/Administration/AdministrationService.cs b/rag-2-backend/Infrastructure/Module/Administration/AdministrationService.cs index 70783cb..2a73f85 100644 --- a/rag-2-backend/Infrastructure/Module/Administration/AdministrationService.cs +++ b/rag-2-backend/Infrastructure/Module/Administration/AdministrationService.cs @@ -48,11 +48,49 @@ public UserResponse GetUserDetails(string principalEmail, int userId) return UserMapper.Map(userDao.GetUserByIdOrThrow(userId)); } - public List GetUsers(SortDirection sortDirection, UserSortByFields sortBy) + public List GetUsers( + string? email, + int? studyCycleYearA, + int? studyCycleYearB, + string? group, + string? courseName, + SortDirection sortDirection, + UserSortByFields sortBy + ) { - var query = context.Users.Include(u=>u.Course).AsQueryable(); + var query = context.Users.Include(u => u.Course).AsQueryable(); - query = sortBy switch + query = FilterUsers(email, studyCycleYearA, studyCycleYearB, group, courseName, query); + query = SortUsers(sortDirection, sortBy, query); + + return query.AsEnumerable().Select(UserMapper.Map).ToList(); + } + + // + + private static IQueryable FilterUsers(string? email, int? studyCycleYearA, + int? studyCycleYearB, string? group, + string? courseName, IQueryable query) + { + if (!string.IsNullOrEmpty(email)) + query = query.Where(u => u.Email.ToLower().Contains(email.ToLower())); + if (studyCycleYearA.HasValue) + query = query.Where(u => u.StudyCycleYearA == studyCycleYearA.Value); + if (studyCycleYearB.HasValue) + query = query.Where(u => u.StudyCycleYearB == studyCycleYearB.Value); + if (!string.IsNullOrEmpty(group)) + query = query.Where(u => u.Group != null && u.Group.ToLower().Contains( + group.ToLower() + )); + if (!string.IsNullOrEmpty(courseName)) + query = query.Where(u => u.Course != null && u.Course.Name.Equals(courseName)); + return query; + } + + private static IQueryable SortUsers(SortDirection sortDirection, UserSortByFields sortBy, + IQueryable query) + { + return sortBy switch { UserSortByFields.Id => ApplySorting(query, x => x.Id, sortDirection), UserSortByFields.Email => ApplySorting(query, x => x.Email, sortDirection), @@ -60,17 +98,16 @@ public List GetUsers(SortDirection sortDirection, UserSortByFields UserSortByFields.StudyYearCycleA => ApplySorting(query, x => x.StudyCycleYearA, sortDirection), UserSortByFields.StudyYearCycleB => ApplySorting(query, x => x.StudyCycleYearB, sortDirection), UserSortByFields.LastPlayed => ApplySorting(query, x => x.LastPlayed, sortDirection), - UserSortByFields.CourseName => ApplySorting(query, x=>x.Course != null ? x.Course.Name : string.Empty, sortDirection), + UserSortByFields.CourseName => ApplySorting(query, x => x.Course != null ? x.Course.Name : string.Empty, + sortDirection), UserSortByFields.Group => ApplySorting(query, x => x.Group, sortDirection), _ => query }; - - return query.AsEnumerable().Select(UserMapper.Map).ToList(); } - private static IQueryable ApplySorting(IQueryable query, Expression> keySelector, SortDirection sortDirection) + private static IQueryable ApplySorting(IQueryable query, Expression> keySelector, + SortDirection sortDirection) { return sortDirection == SortDirection.Desc ? query.OrderByDescending(keySelector) : query.OrderBy(keySelector); } - } \ No newline at end of file diff --git a/rag-2-backend/Infrastructure/Module/Administration/Dto/UserSortByFields.cs b/rag-2-backend/Infrastructure/Module/Administration/Dto/UserSortByFields.cs index 1f3b043..d54e216 100644 --- a/rag-2-backend/Infrastructure/Module/Administration/Dto/UserSortByFields.cs +++ b/rag-2-backend/Infrastructure/Module/Administration/Dto/UserSortByFields.cs @@ -1,8 +1,13 @@ -using System.Text.RegularExpressions; - namespace rag_2_backend.Infrastructure.Module.Administration.Dto; public enum UserSortByFields { - Id, Email, Name, StudyYearCycleA, StudyYearCycleB, LastPlayed, CourseName, Group + Id, + Email, + Name, + StudyYearCycleA, + StudyYearCycleB, + LastPlayed, + CourseName, + Group } \ No newline at end of file diff --git a/rag-2-backend/Test/Service/AdministrationServiceTest.cs b/rag-2-backend/Test/Service/AdministrationServiceTest.cs index 5ef638d..9caac28 100644 --- a/rag-2-backend/Test/Service/AdministrationServiceTest.cs +++ b/rag-2-backend/Test/Service/AdministrationServiceTest.cs @@ -117,7 +117,8 @@ public void ShouldGetStudents() Assert.Equal( JsonConvert.SerializeObject(response), - JsonConvert.SerializeObject(_administrationService.GetUsers(SortDirection.Asc, UserSortByFields.Id)[0]) + JsonConvert.SerializeObject(_administrationService.GetUsers(null, null, null, null, null, SortDirection.Asc, + UserSortByFields.Id)[0]) ); } } \ No newline at end of file