Error handling and fixes
This commit is contained in:
		| @@ -8,6 +8,7 @@ | ||||
|  | ||||
|     <ItemGroup> | ||||
|         <PackageReference Include="AutoMapper" Version="13.0.1" /> | ||||
|         <PackageReference Include="Blazor.Bootstrap" Version="3.0.0" /> | ||||
|         <PackageReference Include="FluentValidation" Version="11.9.2" /> | ||||
|         <PackageReference Include="FluentValidation.DependencyInjectionExtensions" Version="11.9.2" /> | ||||
|         <PackageReference Include="Microsoft.AspNetCore.Components.DataAnnotations.Validation" Version="3.2.0-rc1.20223.4" /> | ||||
| @@ -22,6 +23,8 @@ | ||||
|  | ||||
|     <ItemGroup> | ||||
|       <_ContentIncludedByDefault Remove="wwwroot\sample-data\weather.json" /> | ||||
|       <_ContentIncludedByDefault Remove="wwwroot\css\bootstrap\bootstrap.min.css" /> | ||||
|       <_ContentIncludedByDefault Remove="wwwroot\css\bootstrap\bootstrap.min.css.map" /> | ||||
|     </ItemGroup> | ||||
|  | ||||
| </Project> | ||||
|   | ||||
| @@ -1,26 +1,52 @@ | ||||
| @using System.Net | ||||
| @using BlazorWebAssemblyVisaApiClient.Common.Exceptions | ||||
| @using VisaApiClient | ||||
|  | ||||
| <CascadingValue Value="this"> | ||||
|     <Modal @ref="modal"> | ||||
|         <BodyTemplate> | ||||
|             @errorDetails | ||||
|         </BodyTemplate> | ||||
|         <FooterTemplate> | ||||
|             <Button Color="ButtonColor.Secondary" @onclick="modal.HideAsync">Okaaaay</Button> | ||||
|         </FooterTemplate> | ||||
|     </Modal> | ||||
|     @ChildContent | ||||
| </CascadingValue> | ||||
|  | ||||
| @code | ||||
| { | ||||
|     [Parameter] | ||||
|     public RenderFragment? ChildContent { get; set; } | ||||
|     private Modal modal = null!; | ||||
|     private string errorDetails = null!; | ||||
|  | ||||
|     [Parameter] public RenderFragment? ChildContent { get; set; } | ||||
|  | ||||
|     [Inject] private NavigationManager Nav { get; set; } = null!; | ||||
|  | ||||
|     public void Handle(Exception ex) | ||||
|     { | ||||
|         if (ex is ApiException<ProblemDetails> | ||||
|         switch (ex) | ||||
|         { | ||||
|             case ApiException<ProblemDetails> | ||||
|             { | ||||
|                 StatusCode: (int)HttpStatusCode.Unauthorized or (int)HttpStatusCode.Forbidden | ||||
|             } | ||||
|             or NotLoggedInException) | ||||
|         { | ||||
|             Nav.NavigateTo("/"); | ||||
|             } or NotLoggedInException: | ||||
|                 Nav.NavigateTo("/"); | ||||
|                 modal.Title = "Authorization failed"; | ||||
|                 errorDetails = "You are not authorized or your authorization is expired"; | ||||
|                 break; | ||||
|  | ||||
|             case ApiException<ProblemDetails> problemDetails: | ||||
|                 modal.Title = problemDetails.Result.Title!; | ||||
|                 errorDetails = problemDetails.Result.Detail!; | ||||
|                 modal.ShowAsync(); | ||||
|                 break; | ||||
|  | ||||
|             default: | ||||
|                 modal.Title = "Something went wrong"; | ||||
|                 errorDetails = "Please, text an email with your problem definition on nasrudin@mail.ru"; | ||||
|                 modal.ShowAsync(); | ||||
|                 break; | ||||
|         } | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -1,5 +1,6 @@ | ||||
| @page "/applications/{ApplicationId}" | ||||
| @using BlazorWebAssemblyVisaApiClient.Common.Exceptions | ||||
| @using BlazorWebAssemblyVisaApiClient.Components | ||||
| @using BlazorWebAssemblyVisaApiClient.Infrastructure.Helpers | ||||
| @using BlazorWebAssemblyVisaApiClient.Infrastructure.Services.UserDataProvider | ||||
| @using VisaApiClient | ||||
| @@ -175,15 +176,24 @@ | ||||
|     </tr> | ||||
|     </tbody> | ||||
| </table> | ||||
| @if (currentRole == Constants.ApprovingAuthorityRole) | ||||
| { | ||||
|     <button class="btn-outline-primary" @onclick="Approve">Approve</button> | ||||
|     <button class="btn-outline-danger" @onclick="Reject">Reject</button> | ||||
|     <Status @ref="status"/> | ||||
| } | ||||
|  | ||||
| @code { | ||||
|     private VisaApplicationModel application = new(); | ||||
|     private string currentRole = null!; | ||||
|     private Status status = null!; | ||||
|  | ||||
|     [Parameter] public string ApplicationId { get; set; } = null!; | ||||
|  | ||||
|     [Inject] private IUserDataProvider UserDataProvider { get; set; } = null!; | ||||
|  | ||||
|     [Inject] private NavigationManager Nav { get; set; } = null!; | ||||
|  | ||||
|     protected override async Task OnInitializedAsync() | ||||
|     { | ||||
|         try | ||||
| @@ -191,12 +201,12 @@ | ||||
|             var applicationId = Guid.Parse(ApplicationId); | ||||
|             currentRole = UserDataProvider.GetCurrentRole() ?? throw new NotLoggedInException(); | ||||
|  | ||||
|             application = currentRole switch | ||||
|             { | ||||
|                 Constants.ApplicantRole => await Client.GetApplicationForApplicantAsync(applicationId), | ||||
|                 Constants.ApprovingAuthorityRole => await Client.GetApplicationForAuthorityAsync(applicationId), | ||||
|                 _ => throw new NotLoggedInException() | ||||
|             }; | ||||
|                 application = currentRole switch | ||||
|                 { | ||||
|                     Constants.ApplicantRole => await Client.GetApplicationForApplicantAsync(applicationId), | ||||
|                     Constants.ApprovingAuthorityRole => await Client.GetApplicationForAuthorityAsync(applicationId), | ||||
|                     _ => throw new NotLoggedInException() | ||||
|                 }; | ||||
|         } | ||||
|         catch (Exception e) | ||||
|         { | ||||
| @@ -210,4 +220,34 @@ | ||||
|     private static string AddressToString(AddressModel address) | ||||
|         => $"{address.Country}, {address.City}, {address.Street} {address.Building}"; | ||||
|  | ||||
|     private async void Approve() | ||||
|     { | ||||
|         try | ||||
|         { | ||||
|             status.SetMessage("Wait..."); | ||||
|             await Client.SetStatusFromAuthorityAsync(application.Id, AuthorityRequestStatuses.Approved); | ||||
|             Nav.NavigateTo("/applications"); | ||||
|         } | ||||
|         catch (Exception e) | ||||
|         { | ||||
|             status.SetError("Error occured."); | ||||
|             ErrorHandler.Handle(e); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     private async void Reject() | ||||
|     { | ||||
|         try | ||||
|         { | ||||
|             status.SetMessage("Wait..."); | ||||
|             await Client.SetStatusFromAuthorityAsync(application.Id, AuthorityRequestStatuses.Rejected); | ||||
|             Nav.NavigateTo("/applications"); | ||||
|         } | ||||
|         catch (Exception e) | ||||
|         { | ||||
|             status.SetError("Error occured."); | ||||
|             ErrorHandler.Handle(e); | ||||
|         } | ||||
|     } | ||||
|  | ||||
| } | ||||
|   | ||||
| @@ -41,7 +41,7 @@ | ||||
|                 <NavLink href="@($"/applications/{application.Id}")"> | ||||
|                     <button class="btn-outline-primary">See</button> | ||||
|                 </NavLink> | ||||
|                 @if (currentRole == Constants.ApplicantRole && application.Status is not ApplicationStatus.Closed) | ||||
|                 @if (currentRole == Constants.ApplicantRole && application.Status is ApplicationStatus.Pending) | ||||
|                 { | ||||
|                     <span> | </span> | ||||
|                     <input type="button" class="border-danger" @onclick="() => CloseApplication(application)" value="Close"/> | ||||
| @@ -70,7 +70,7 @@ | ||||
|         { | ||||
|             applications = currentRole switch | ||||
|             { | ||||
|                 Constants.ApplicantRole => (await Client.GetForApplicantAsync()).OrderByDescending(a => a.RequestDate).ToList(), | ||||
|                 Constants.ApplicantRole => (await Client.GetApplicationsForApplicantAsync()).OrderByDescending(a => a.RequestDate).ToList(), | ||||
|                 Constants.ApprovingAuthorityRole => (await Client.GetPendingAsync()).OrderByDescending(a => a.RequestDate).ToList(), | ||||
|                 _ => throw new NotLoggedInException() | ||||
|             }; | ||||
|   | ||||
| @@ -267,7 +267,7 @@ | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 ErrorHandler.Handle(e); | ||||
|                 throw; | ||||
|             } | ||||
|         } | ||||
|         catch (Exception e) | ||||
|   | ||||
| @@ -172,7 +172,6 @@ | ||||
|                 if (errorsList is null) | ||||
|                 { | ||||
|                     ErrorHandler.Handle(new JsonException("Can't convert validation errors to list")); | ||||
|  | ||||
|                     return; | ||||
|                 } | ||||
|  | ||||
| @@ -180,7 +179,7 @@ | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 ErrorHandler.Handle(e); | ||||
|                 throw; | ||||
|             } | ||||
|         } | ||||
|         catch (Exception e) | ||||
|   | ||||
| @@ -21,6 +21,7 @@ public class Program | ||||
|  | ||||
|         //todo make pretty | ||||
|         builder.Services.AddScoped(_ => new HttpClient { BaseAddress = new Uri(baseAddress) }); | ||||
|         builder.Services.AddBlazorBootstrap(); | ||||
|         builder.Services.AddScoped<Client>(sp => new Client(baseAddress, sp.GetRequiredService<HttpClient>())); | ||||
|  | ||||
|         builder.Services.AddSingleton<IDateTimeProvider, DateTimeProvider>(); | ||||
|   | ||||
| @@ -8,3 +8,4 @@ | ||||
| @using Microsoft.JSInterop | ||||
| @using BlazorWebAssemblyVisaApiClient | ||||
| @using BlazorWebAssemblyVisaApiClient.Layout | ||||
| @using BlazorBootstrap | ||||
|   | ||||
| @@ -7,6 +7,9 @@ | ||||
|     <title>BlazorWebAssemblyVisaApiClient</title> | ||||
|     <base href="/" /> | ||||
|     <link rel="stylesheet" href="css/bootstrap/bootstrap.min.css" /> | ||||
|     <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-T3c6CoIi6uLrA9TneNEoa7RxnatzjcDSCmG1MXxSR1GAsXEV/Dwwykc2MPK8M2HN" crossorigin="anonymous"> | ||||
|     <link href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css" rel="stylesheet" /> | ||||
|     <link href="_content/Blazor.Bootstrap/blazor.bootstrap.css" rel="stylesheet" /> | ||||
|     <link rel="stylesheet" href="css/app.css" /> | ||||
|     <link rel="icon" type="image/png" href="favicon.png" /> | ||||
|     <link href="BlazorWebAssemblyVisaApiClient.styles.css" rel="stylesheet" /> | ||||
| @@ -27,6 +30,14 @@ | ||||
|         <a class="dismiss">🗙</a> | ||||
|     </div> | ||||
|     <script src="_framework/blazor.webassembly.js"></script> | ||||
|     <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-C6RzsynM9kWDrMNeT87bh95OGNyZPhcTNXj1NW7RuBCsyN/o0jlpcV8Qyq46cDfL" crossorigin="anonymous"></script> | ||||
|     <!-- Add chart.js reference if chart components are used in your application. --> | ||||
|     <script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/4.0.1/chart.umd.js" integrity="sha512-gQhCDsnnnUfaRzD8k1L5llCCV6O9HN09zClIzzeJ8OJ9MpGmIlCxm+pdCkqTwqJ4JcjbojFr79rl2F1mzcoLMQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script> | ||||
|     <!-- Add chartjs-plugin-datalabels.min.js reference if chart components with data label feature is used in your application. --> | ||||
|     <script src="https://cdnjs.cloudflare.com/ajax/libs/chartjs-plugin-datalabels/2.2.0/chartjs-plugin-datalabels.min.js" integrity="sha512-JPcRR8yFa8mmCsfrw4TNte1ZvF1e3+1SdGMslZvmrzDYxS69J7J49vkFL8u6u8PlPJK+H3voElBtUCzaXj+6ig==" crossorigin="anonymous" referrerpolicy="no-referrer"></script> | ||||
|     <!-- Add sortable.js reference if SortableList component is used in your application. --> | ||||
|     <script src="https://cdn.jsdelivr.net/npm/sortablejs@latest/Sortable.min.js"></script> | ||||
|     <script src="_content/Blazor.Bootstrap/blazor.bootstrap.js"></script> | ||||
| </body> | ||||
|  | ||||
| </html> | ||||
|   | ||||
		Reference in New Issue
	
	Block a user