From 8f55b1b56a22d59474097007c170ec1741e0dde1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Michel?= Date: Mon, 25 Oct 2021 23:32:07 +0200 Subject: [PATCH] manage conflict (generic way) use toast to show error (#588) * manage conflict (generic way) use toast to show error * fix httpservice after merge conflict, adapt to use new repository --- .../DuplicateCatalogItemNameException.cs | 14 --- .../Exceptions/DuplicateException.cs | 14 +++ .../CatalogItemNameSpecification.cs | 13 +++ src/BlazorAdmin/Helpers/ToastComponent.cs | 88 +++++++++++++++++++ .../Pages/CatalogItemPage/Create.razor | 22 +++-- src/BlazorAdmin/Program.cs | 4 +- .../Services/CatalogItemService.cs | 3 +- src/BlazorAdmin/Services/HttpService.cs | 14 ++- src/BlazorAdmin/Services/ToastService.cs | 55 ++++++++++++ src/BlazorAdmin/Shared/MainLayout.razor | 3 + src/BlazorAdmin/Shared/Toast.razor | 13 +++ src/BlazorAdmin/wwwroot/css/admin.css | 47 ++++++++++ src/BlazorShared/Models/ErrorDetails.cs | 14 +++ src/PublicApi/CatalogItemEndpoints/Create.cs | 11 ++- .../MiddleWares/ExceptionMiddleware.cs | 46 ++++++++++ src/PublicApi/Startup.cs | 3 + src/Web/Startup.cs | 2 + 17 files changed, 337 insertions(+), 29 deletions(-) delete mode 100644 src/ApplicationCore/Exceptions/DuplicateCatalogItemNameException.cs create mode 100644 src/ApplicationCore/Exceptions/DuplicateException.cs create mode 100644 src/ApplicationCore/Specifications/CatalogItemNameSpecification.cs create mode 100644 src/BlazorAdmin/Helpers/ToastComponent.cs create mode 100644 src/BlazorAdmin/Services/ToastService.cs create mode 100644 src/BlazorAdmin/Shared/Toast.razor create mode 100644 src/BlazorShared/Models/ErrorDetails.cs create mode 100644 src/PublicApi/MiddleWares/ExceptionMiddleware.cs diff --git a/src/ApplicationCore/Exceptions/DuplicateCatalogItemNameException.cs b/src/ApplicationCore/Exceptions/DuplicateCatalogItemNameException.cs deleted file mode 100644 index 09fe302..0000000 --- a/src/ApplicationCore/Exceptions/DuplicateCatalogItemNameException.cs +++ /dev/null @@ -1,14 +0,0 @@ -using System; - -namespace Microsoft.eShopWeb.ApplicationCore.Exceptions -{ - public class DuplicateCatalogItemNameException : Exception - { - public DuplicateCatalogItemNameException(string message, int duplicateItemId) : base(message) - { - DuplicateItemId = duplicateItemId; - } - - public int DuplicateItemId { get; } - } -} diff --git a/src/ApplicationCore/Exceptions/DuplicateException.cs b/src/ApplicationCore/Exceptions/DuplicateException.cs new file mode 100644 index 0000000..96bd24b --- /dev/null +++ b/src/ApplicationCore/Exceptions/DuplicateException.cs @@ -0,0 +1,14 @@ +using System; + +namespace Microsoft.eShopWeb.ApplicationCore.Exceptions +{ + + public class DuplicateException : Exception + { + public DuplicateException(string message) : base(message) + { + + } + + } +} diff --git a/src/ApplicationCore/Specifications/CatalogItemNameSpecification.cs b/src/ApplicationCore/Specifications/CatalogItemNameSpecification.cs new file mode 100644 index 0000000..2a2b9e3 --- /dev/null +++ b/src/ApplicationCore/Specifications/CatalogItemNameSpecification.cs @@ -0,0 +1,13 @@ +using Ardalis.Specification; +using Microsoft.eShopWeb.ApplicationCore.Entities; + +namespace Microsoft.eShopWeb.ApplicationCore.Specifications +{ + public class CatalogItemNameSpecification : Specification + { + public CatalogItemNameSpecification(string catalogItemName) + { + Query.Where(item => string.Compare(catalogItemName, item.Name, true) == 0); + } + } +} diff --git a/src/BlazorAdmin/Helpers/ToastComponent.cs b/src/BlazorAdmin/Helpers/ToastComponent.cs new file mode 100644 index 0000000..5babca1 --- /dev/null +++ b/src/BlazorAdmin/Helpers/ToastComponent.cs @@ -0,0 +1,88 @@ +using BlazorAdmin.Services; +using Microsoft.AspNetCore.Components; +using System; + +namespace BlazorAdmin.Helpers +{ + public class ToastComponent : ComponentBase, IDisposable + { + [Inject] + ToastService ToastService + { + get; + set; + } + protected string Heading + { + get; + set; + } + protected string Message + { + get; + set; + } + protected bool IsVisible + { + get; + set; + } + protected string BackgroundCssClass + { + get; + set; + } + protected string IconCssClass + { + get; + set; + } + protected override void OnInitialized() + { + ToastService.OnShow += ShowToast; + ToastService.OnHide += HideToast; + } + private void ShowToast(string message, ToastLevel level) + { + BuildToastSettings(level, message); + IsVisible = true; + StateHasChanged(); + } + private void HideToast() + { + IsVisible = false; + StateHasChanged(); + } + private void BuildToastSettings(ToastLevel level, string message) + { + switch (level) + { + case ToastLevel.Info: + BackgroundCssClass = "bg-info"; + IconCssClass = "info"; + Heading = "Info"; + break; + case ToastLevel.Success: + BackgroundCssClass = "bg-success"; + IconCssClass = "check"; + Heading = "Success"; + break; + case ToastLevel.Warning: + BackgroundCssClass = "bg-warning"; + IconCssClass = "exclamation"; + Heading = "Warning"; + break; + case ToastLevel.Error: + BackgroundCssClass = "bg-danger"; + IconCssClass = "times"; + Heading = "Error"; + break; + } + Message = message; + } + public void Dispose() + { + ToastService.OnShow -= ShowToast; + } + } +} diff --git a/src/BlazorAdmin/Pages/CatalogItemPage/Create.razor b/src/BlazorAdmin/Pages/CatalogItemPage/Create.razor index 0101526..8bc5c23 100644 --- a/src/BlazorAdmin/Pages/CatalogItemPage/Create.razor +++ b/src/BlazorAdmin/Pages/CatalogItemPage/Create.razor @@ -106,13 +106,13 @@ @code { - [Parameter] - public IEnumerable Brands { get; set; } - [Parameter] - public IEnumerable Types { get; set; } + [Parameter] + public IEnumerable Brands { get; set; } + [Parameter] + public IEnumerable Types { get; set; } - [Parameter] - public EventCallback OnSaveClick { get; set; } + [Parameter] + public EventCallback OnSaveClick { get; set; } private string LoadPicture => string.IsNullOrEmpty(_item.PictureBase64) ? string.Empty : $"data:image/png;base64, {_item.PictureBase64}"; private bool HasPicture => !string.IsNullOrEmpty(_item.PictureBase64); @@ -124,13 +124,17 @@ private async Task CreateClick() { - await CatalogItemService.Create(_item); - await OnSaveClick.InvokeAsync(null); - await Close(); + var result = await CatalogItemService.Create(_item); + if (result != null) + { + await OnSaveClick.InvokeAsync(null); + await Close(); + } } public async Task Open() { + Logger.LogInformation("Now loading... /Catalog/Create"); await new Css(JSRuntime).HideBodyOverflow(); diff --git a/src/BlazorAdmin/Program.cs b/src/BlazorAdmin/Program.cs index 1abed16..2751bc1 100644 --- a/src/BlazorAdmin/Program.cs +++ b/src/BlazorAdmin/Program.cs @@ -25,14 +25,16 @@ namespace BlazorAdmin builder.Services.AddScoped(sp => new HttpClient() { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) }); + builder.Services.AddScoped(); builder.Services.AddScoped(); + builder.Services.AddScoped(); builder.Services.AddAuthorizationCore(); builder.Services.AddScoped(); builder.Services.AddScoped(sp => (CustomAuthStateProvider)sp.GetRequiredService()); - + builder.Services.AddBlazorServices(); builder.Logging.AddConfiguration(builder.Configuration.GetSection("Logging")); diff --git a/src/BlazorAdmin/Services/CatalogItemService.cs b/src/BlazorAdmin/Services/CatalogItemService.cs index bc75c4c..fb8194f 100644 --- a/src/BlazorAdmin/Services/CatalogItemService.cs +++ b/src/BlazorAdmin/Services/CatalogItemService.cs @@ -33,7 +33,8 @@ namespace BlazorAdmin.Services public async Task Create(CreateCatalogItemRequest catalogItem) { - return (await _httpService.HttpPost("catalog-items", catalogItem)).CatalogItem; + var response = await _httpService.HttpPost("catalog-items", catalogItem); + return response?.CatalogItem; } public async Task Edit(CatalogItem catalogItem) diff --git a/src/BlazorAdmin/Services/HttpService.cs b/src/BlazorAdmin/Services/HttpService.cs index d0b8584..67cac1e 100644 --- a/src/BlazorAdmin/Services/HttpService.cs +++ b/src/BlazorAdmin/Services/HttpService.cs @@ -1,4 +1,5 @@ using BlazorShared; +using BlazorShared.Models; using System.Net.Http; using System.Text; using System.Text.Json; @@ -9,11 +10,14 @@ namespace BlazorAdmin.Services public class HttpService { private readonly HttpClient _httpClient; + private readonly ToastService _toastService; private readonly string _apiUrl; - public HttpService(HttpClient httpClient, BaseUrlConfiguration baseUrlConfiguration) + + public HttpService(HttpClient httpClient, BaseUrlConfiguration baseUrlConfiguration, ToastService toastService) { _httpClient = httpClient; + _toastService = toastService; _apiUrl = baseUrlConfiguration.ApiBase; } @@ -49,6 +53,12 @@ namespace BlazorAdmin.Services var result = await _httpClient.PostAsync($"{_apiUrl}{uri}", content); if (!result.IsSuccessStatusCode) { + var exception = JsonSerializer.Deserialize(await result.Content.ReadAsStringAsync(), new JsonSerializerOptions + { + PropertyNameCaseInsensitive = true + }); + _toastService.ShowToast($"Error : {exception.Message}", ToastLevel.Error); + return null; } @@ -63,13 +73,13 @@ namespace BlazorAdmin.Services var result = await _httpClient.PutAsync($"{_apiUrl}{uri}", content); if (!result.IsSuccessStatusCode) { + _toastService.ShowToast("Error", ToastLevel.Error); return null; } return await FromHttpResponseMessage(result); } - private StringContent ToJson(object obj) { return new StringContent(JsonSerializer.Serialize(obj), Encoding.UTF8, "application/json"); diff --git a/src/BlazorAdmin/Services/ToastService.cs b/src/BlazorAdmin/Services/ToastService.cs new file mode 100644 index 0000000..fe503f2 --- /dev/null +++ b/src/BlazorAdmin/Services/ToastService.cs @@ -0,0 +1,55 @@ +using System; +using System.Timers; + +namespace BlazorAdmin.Services +{ + public enum ToastLevel + { + Info, + Success, + Warning, + Error + } + + public class ToastService : IDisposable + { + public event Action OnShow; + public event Action OnHide; + private Timer Countdown; + public void ShowToast(string message, ToastLevel level) + { + OnShow?.Invoke(message, level); + StartCountdown(); + } + private void StartCountdown() + { + SetCountdown(); + if (Countdown.Enabled) + { + Countdown.Stop(); + Countdown.Start(); + } + else + { + Countdown.Start(); + } + } + private void SetCountdown() + { + if (Countdown == null) + { + Countdown = new Timer(3000); + Countdown.Elapsed += HideToast; + Countdown.AutoReset = false; + } + } + private void HideToast(object source, ElapsedEventArgs args) + { + OnHide?.Invoke(); + } + public void Dispose() + { + Countdown?.Dispose(); + } + } +} diff --git a/src/BlazorAdmin/Shared/MainLayout.razor b/src/BlazorAdmin/Shared/MainLayout.razor index 964427e..a7d8383 100644 --- a/src/BlazorAdmin/Shared/MainLayout.razor +++ b/src/BlazorAdmin/Shared/MainLayout.razor @@ -3,6 +3,7 @@ @inherits BlazorAdmin.Helpers.BlazorLayoutComponent +