From 39ed6a9ac7306bbbbbd3d7026e1edfbd0386ad9e Mon Sep 17 00:00:00 2001 From: samuel Date: Wed, 17 Jan 2024 17:37:15 +0100 Subject: [PATCH] WIP --- Models/Team.cs | 2 +- Pages/DisplayUtils.cs | 24 +++++++++ Pages/TeamListPanel.razor | 102 +++++++++++++++++++++++++++++------ Pages/TeamListPanel.razor.cs | 97 ++++++++++++++++++++++++++------- Pages/UserListPanel.razor.cs | 24 ++------- Program.cs | 1 + Services/ErrorsUtils.cs | 27 ++++++++++ Services/HttpTeamService.cs | 24 +++++++-- Services/HttpUsersService.cs | 31 ++--------- Services/ITeamService.cs | 4 +- Services/ServiceException.cs | 7 ++- Shared/MainLayout.razor | 5 -- 12 files changed, 254 insertions(+), 94 deletions(-) create mode 100644 Pages/DisplayUtils.cs create mode 100644 Services/ErrorsUtils.cs diff --git a/Models/Team.cs b/Models/Team.cs index 4794ee3..b4f7f20 100644 --- a/Models/Team.cs +++ b/Models/Team.cs @@ -1,6 +1,6 @@ namespace AdminPanel.Models; -public record Team(string Name, string Picture, string MainColor, string SecondColor) +public record Team(uint Id, string Name, string Picture, string MainColor, string SecondColor) { } \ No newline at end of file diff --git a/Pages/DisplayUtils.cs b/Pages/DisplayUtils.cs new file mode 100644 index 0000000..fd30ce9 --- /dev/null +++ b/Pages/DisplayUtils.cs @@ -0,0 +1,24 @@ +using System.Text; +using AdminPanel.Services; +using MudBlazor; + +namespace AdminPanel.Pages; + +public class DisplayUtils +{ + public static void ShowErrors(ServiceException e, ISnackbar snackbar) + { + foreach (var erronedArgument in e.ArgumentMessages) + { + var sb = new StringBuilder(erronedArgument.Key); + sb.Append(" :"); + + foreach (var message in erronedArgument.Value) + { + sb.Append("\n\t-"); + sb.Append(message); + } + snackbar.Add(sb.ToString()); + } + } +} \ No newline at end of file diff --git a/Pages/TeamListPanel.razor b/Pages/TeamListPanel.razor index 862dbc6..b6b5659 100644 --- a/Pages/TeamListPanel.razor +++ b/Pages/TeamListPanel.razor @@ -1,16 +1,40 @@ @page "/teams" @using AdminPanel.Models +@using DataGridEditMode = MudBlazor.DataGridEditMode Teams Panel - +

Team Panel

+ + +
- - - - - + + + + +
Apply
@@ -18,19 +42,65 @@ Close
+ - - Ajouter - - - + + +
+ + Add Team +
+
+ + Remove selection +
+ + + Teams + +
+ + + + +
+ +

Are you sure you want to delete this team(s)?

+
+
+ Confirm + Close +
+
+
+ + - - - - + + + + + + + + + + - + diff --git a/Pages/TeamListPanel.razor.cs b/Pages/TeamListPanel.razor.cs index 374a178..c3c8dd1 100644 --- a/Pages/TeamListPanel.razor.cs +++ b/Pages/TeamListPanel.razor.cs @@ -1,6 +1,8 @@ -using System.Net.Http.Json; +using System.ComponentModel.DataAnnotations; +using System.Text; using AdminPanel.Models; using AdminPanel.Services; +using Blazorise.Extensions; using Microsoft.AspNetCore.Components; using MudBlazor; @@ -8,45 +10,100 @@ namespace AdminPanel.Pages; public partial class TeamListPanel { - [Inject] - private ITeamService TeamService { get; init; } - private bool _isOpen; - private MudForm form; - bool success; - string[] errors = { }; - + [Inject] private ISnackbar Snackbar { get; init; } + [Inject] private ITeamService TeamService { get; init; } + private bool _isOpenAdd; + private bool _isOpenConf; + private bool success; + private string[] errors = { }; + + [StringLength(1,ErrorMessage = "Nombre de caractères minimal : 1 ")] private string? FormName { get; set; } + + [RegularExpression(@"(https:\/\/www\.|http:\/\/www\.|https:\/\/|http:\/\/)?[a-zA-Z0-9]{2,}\.[a-zA-Z0-9]{2,}\.[a-zA-Z0-9]{2,}(\.[a-zA-Z0-9]{2,})?", ErrorMessage = "L'image doit être le lien d'une image sur le web")] private string? FormPicture { get; set; } + + [RegularExpression(@"(/#[0-9a-f]{6})",ErrorMessage = "La couleur principale doit être un code hexadécimal")] private string? FormMainColor { get; set; } - private string? FormSecondaryColor { get; set; } - - + [RegularExpression(@"(/#[0-9a-f]{6})",ErrorMessage = "La couleur secondaire doit être un code hexadécimal")] + private string? FormSecondaryColor { get; set; } + private MudDataGrid? Grid { get; set; } + private HashSet SelectedTeams { get; set; } = new(); + + private void UnBindForm() + { + FormName = null; + FormPicture = null; + FormMainColor = null; + FormSecondaryColor = null; + } private async Task> GetTeamsFromServer(GridState state) { var (count, teams) = await TeamService.ListTeam((uint)(state.Page * state.PageSize), (uint)state.PageSize); return new GridData { - TotalItems = (int) count, + TotalItems = (int)count, Items = teams }; } + private void ToggleOpen() - { - _isOpen = !(_isOpen); + { + _isOpenAdd = !(_isOpenAdd); } - - private async void AddTeam() + + private void ToggleOpenConfirmation() { - await TeamService.AddTeam(FormName!,FormPicture!,FormMainColor!,FormSecondaryColor!); + _isOpenConf = !(_isOpenConf); } - private void AddTeamConfirmed() + private async Task AddTeam() { - AddTeam(); + try + { + await TeamService.AddTeam(FormName!, FormPicture!, FormMainColor!, FormSecondaryColor!); + } + catch (ServiceException err) + { + DisplayUtils.ShowErrors(err,Snackbar); + } + } + + private async void AddTeamConfirmed() + { + await AddTeam(); ToggleOpen(); + await Grid!.ReloadServerData(); + UnBindForm(); } -} + private async void DeleteSelectedTeams() + { + if (!SelectedTeams.IsNullOrEmpty()) + { + var ids = SelectedTeams.ToList().ConvertAll(team => team.Id); + await TeamService.DeleteTeams(ids); + await Grid!.ReloadServerData(); + } + CloseToggleConf(); + } + private void CloseToggleConf() + { + _isOpenConf = false; + } + + private async void OnTeamUpdated(Team t) + { + try + { + await TeamService.UpdateTeam(t); + } + catch (ServiceException err) + { + DisplayUtils.ShowErrors(err,Snackbar); + } + } +} \ No newline at end of file diff --git a/Pages/UserListPanel.razor.cs b/Pages/UserListPanel.razor.cs index 45eaaa6..3b3d51d 100644 --- a/Pages/UserListPanel.razor.cs +++ b/Pages/UserListPanel.razor.cs @@ -52,7 +52,7 @@ namespace AdminPanel.Pages } catch (ServiceException err) { - ShowErrors(err); + DisplayUtils.ShowErrors(err,Snackbar); } } @@ -70,26 +70,10 @@ namespace AdminPanel.Pages } catch (ServiceException err) { - ShowErrors(err); - } - } - - - private void ShowErrors(ServiceException e) - { - foreach (var erronedArgument in e.ArgumentMessages) - { - var sb = new StringBuilder(erronedArgument.Key); - sb.Append(" :"); - - foreach (var message in erronedArgument.Value) - { - sb.Append("\n\t-"); - sb.Append(message); - } - Snackbar.Add(sb.ToString()); + DisplayUtils.ShowErrors(err,Snackbar); } } + private async void RemoveSelection(MouseEventArgs e) { @@ -102,7 +86,7 @@ namespace AdminPanel.Pages } catch (ServiceException err) { - ShowErrors(err); + DisplayUtils.ShowErrors(err,Snackbar); } } diff --git a/Program.cs b/Program.cs index a4c2a12..ae3bdd6 100644 --- a/Program.cs +++ b/Program.cs @@ -19,6 +19,7 @@ var client = new HttpClient builder.Services.AddScoped(sp => new HttpUsersService(client)); //builder.Services.AddScoped(); +builder.Services.AddScoped(sp => new HttpTeamService(client)); builder.Services.AddMudServices(); diff --git a/Services/ErrorsUtils.cs b/Services/ErrorsUtils.cs new file mode 100644 index 0000000..62c3e8c --- /dev/null +++ b/Services/ErrorsUtils.cs @@ -0,0 +1,27 @@ +using System.Net; +using System.Net.Http.Json; + +namespace AdminPanel.Services; + +public class ErrorsUtils +{ + private record ServerErrorMessageDto(string? Field, string? Error, string Message); + + public static async Task EnsureResponseIsOk(HttpResponseMessage response) + { + if (response.StatusCode == HttpStatusCode.OK) + { + return; + } + + var content = await response.Content.ReadFromJsonAsync(); + var messages = content! + .GroupBy(e => e.Field ?? e.Error!) + .ToDictionary( + g => g.Key, + g => g.ToList().ConvertAll(e => e.Message) + ); + + throw new ServiceException("Server refused request", messages); + } +} \ No newline at end of file diff --git a/Services/HttpTeamService.cs b/Services/HttpTeamService.cs index 0b0f1a5..6f38f26 100644 --- a/Services/HttpTeamService.cs +++ b/Services/HttpTeamService.cs @@ -24,11 +24,27 @@ public class HttpTeamService : ITeamService return (response.TotalCount, response.Teams); } - private record AddTeamRequest(string Name, string Picture, string MainColor, string SecondaryColor); + private record AddTeamDTORequest(string Name, string Picture, string MainColor, string SecondaryColor); - public async Task AddTeam(string name, string Picture, string mainColor, string secondaryColor) + public async Task AddTeam(string name, string picture, string mainColor, string secondaryColor) { - var httpResponse = await _client.PostAsJsonAsync($"/api/admin/add-team", new AddTeamRequest(name,Picture,mainColor,secondaryColor)); - httpResponse.EnsureSuccessStatusCode(); + var httpResponse = await _client.PostAsJsonAsync($"/api/admin/add-team", new AddTeamDTORequest(name,picture,mainColor,secondaryColor)); + await ErrorsUtils.EnsureResponseIsOk(httpResponse); + } + + private record DeleteTeamsDTORequest(List Teams); + public async Task DeleteTeams(List teams) + { + var httpResponse = await _client.PostAsJsonAsync($"/api/admin/delete-teams", new DeleteTeamsDTORequest(teams)); + await ErrorsUtils.EnsureResponseIsOk(httpResponse); + + } + + private record UpdateTeamDTORequest(uint Id, string Name, string Picture, string MainColor, string SecondaryColor); + public async Task UpdateTeam(Team team) + { + var httpResponse = await _client.PostAsJsonAsync($"/api/admin/team/{team.Id}/update", + new UpdateTeamDTORequest(team.Id, team.Name, team.Picture, team.MainColor, team.SecondColor) ); + await ErrorsUtils.EnsureResponseIsOk(httpResponse); } } \ No newline at end of file diff --git a/Services/HttpUsersService.cs b/Services/HttpUsersService.cs index 824fefd..3582edc 100644 --- a/Services/HttpUsersService.cs +++ b/Services/HttpUsersService.cs @@ -13,35 +13,14 @@ public class HttpUsersService : IUsersService { this.Client = client; } - - private record ServerErrorMessageDto(string? Field, string? Error, string Message); - - private async Task EnsureResponseIsOk(HttpResponseMessage response) - { - - if (response.StatusCode == HttpStatusCode.OK) - { - return; - } - - var content = await response.Content.ReadFromJsonAsync(); - var messages = content! - .GroupBy(e => e.Field ?? e.Error!) - .ToDictionary( - g => g.Key, - g => g.ToList().ConvertAll(e => e.Message) - ); - - throw new ServiceException("Server refused request", messages); - } - + private record ListUsersResponseDto(List Users, uint TotalCount); public async Task<(uint, List)> ListUsers(uint from, uint len, string? searchString = null) { var httpResponse = await Client.GetAsync($"/api/admin/list-users?start={from}&n={len}&search={searchString ?? ""}"); - await EnsureResponseIsOk(httpResponse); + await ErrorsUtils.EnsureResponseIsOk(httpResponse); var response = await httpResponse.Content.ReadFromJsonAsync() ?? throw new Exception("Received non-parseable json from server"); @@ -58,7 +37,7 @@ public class HttpUsersService : IUsersService var httpResponse = await Client.PostAsJsonAsync("/api/admin/user/add", new AddUserRequestDto(username, email, password, isAdmin)); - await EnsureResponseIsOk(httpResponse); + await ErrorsUtils.EnsureResponseIsOk(httpResponse); var response = await httpResponse.Content.ReadFromJsonAsync() ?? throw new Exception("Received non-parseable json from server"); @@ -79,7 +58,7 @@ public class HttpUsersService : IUsersService var httpResponse = await Client.PostAsJsonAsync("/api/admin/user/remove-all", new RemoveUsersRequestDto(userIds.ToArray())); - await EnsureResponseIsOk(httpResponse); + await ErrorsUtils.EnsureResponseIsOk(httpResponse); } private record UpdateUserRequestDto(string Email, string Username, bool IsAdmin); @@ -88,6 +67,6 @@ public class HttpUsersService : IUsersService { var httpResponse = await Client.PostAsJsonAsync($"/api/admin/user/{user.Id}/update", new UpdateUserRequestDto(user.Email, user.Name, user.IsAdmin)); - await EnsureResponseIsOk(httpResponse); + await ErrorsUtils.EnsureResponseIsOk(httpResponse); } } \ No newline at end of file diff --git a/Services/ITeamService.cs b/Services/ITeamService.cs index c1ac34b..163d883 100644 --- a/Services/ITeamService.cs +++ b/Services/ITeamService.cs @@ -5,6 +5,8 @@ namespace AdminPanel.Services; public interface ITeamService { public Task<(uint, List)> ListTeam(uint from, uint count); - public Task AddTeam(string name, string Picture, string mainColor, string secondaryColor); + public Task AddTeam(string name, string picture, string mainColor, string secondaryColor); + public Task DeleteTeams(List teams); + public Task UpdateTeam(Team team); } \ No newline at end of file diff --git a/Services/ServiceException.cs b/Services/ServiceException.cs index 8dbcb00..853efac 100644 --- a/Services/ServiceException.cs +++ b/Services/ServiceException.cs @@ -1,6 +1,9 @@ +using System.Net; +using System.Net.Http.Json; + namespace AdminPanel.Services; -class ServiceException : Exception +public class ServiceException : Exception { public Dictionary> ArgumentMessages { get; init; } @@ -15,4 +18,6 @@ class ServiceException : Exception { ArgumentMessages = arguments; } + + } \ No newline at end of file diff --git a/Shared/MainLayout.razor b/Shared/MainLayout.razor index c601bdc..dc88df5 100644 --- a/Shared/MainLayout.razor +++ b/Shared/MainLayout.razor @@ -4,11 +4,6 @@ - - - - -