Implemented handling of server side issues using the rfc for problem detasils in the frontend
This commit is contained in:
30
Moonlight.Frontend/Helpers/ProblemDetailsHelper.cs
Normal file
30
Moonlight.Frontend/Helpers/ProblemDetailsHelper.cs
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
using System.Net.Http.Json;
|
||||||
|
using Microsoft.AspNetCore.Components.Forms;
|
||||||
|
using Moonlight.Shared.Http.Responses;
|
||||||
|
|
||||||
|
namespace Moonlight.Frontend.Helpers;
|
||||||
|
|
||||||
|
public static class ProblemDetailsHelper
|
||||||
|
{
|
||||||
|
public static async Task HandleProblemDetailsAsync(HttpResponseMessage response, object model, ValidationMessageStore validationMessageStore)
|
||||||
|
{
|
||||||
|
var problemDetails = await response.Content.ReadFromJsonAsync<ProblemDetails>();
|
||||||
|
|
||||||
|
if (problemDetails == null)
|
||||||
|
response.EnsureSuccessStatusCode(); // Trigger exception when unable to parse
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(!string.IsNullOrEmpty(problemDetails.Detail))
|
||||||
|
validationMessageStore.Add(new FieldIdentifier(model, string.Empty), problemDetails.Detail);
|
||||||
|
|
||||||
|
if (problemDetails.Errors != null)
|
||||||
|
{
|
||||||
|
foreach (var error in problemDetails.Errors)
|
||||||
|
{
|
||||||
|
foreach (var message in error.Value)
|
||||||
|
validationMessageStore.Add(new FieldIdentifier(model, error.Key), message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,12 +1,18 @@
|
|||||||
@using Moonlight.Frontend.UI.Admin.Components
|
@using Moonlight.Frontend.Helpers
|
||||||
|
@using Moonlight.Frontend.UI.Admin.Components
|
||||||
@using Moonlight.Shared.Http.Requests.ApiKeys
|
@using Moonlight.Shared.Http.Requests.ApiKeys
|
||||||
|
@using Moonlight.Shared.Http.Responses
|
||||||
@using ShadcnBlazor.Dialogs
|
@using ShadcnBlazor.Dialogs
|
||||||
@using ShadcnBlazor.Extras.Forms
|
@using ShadcnBlazor.Extras.Forms
|
||||||
|
@using ShadcnBlazor.Extras.Toasts
|
||||||
@using ShadcnBlazor.Fields
|
@using ShadcnBlazor.Fields
|
||||||
@using ShadcnBlazor.Inputs
|
@using ShadcnBlazor.Inputs
|
||||||
|
|
||||||
@inherits ShadcnBlazor.Extras.Dialogs.DialogBase
|
@inherits ShadcnBlazor.Extras.Dialogs.DialogBase
|
||||||
|
|
||||||
|
@inject HttpClient HttpClient
|
||||||
|
@inject ToastService ToastService
|
||||||
|
|
||||||
<DialogHeader>
|
<DialogHeader>
|
||||||
<DialogTitle>Create new API key</DialogTitle>
|
<DialogTitle>Create new API key</DialogTitle>
|
||||||
<DialogDescription>
|
<DialogDescription>
|
||||||
@@ -44,7 +50,7 @@
|
|||||||
|
|
||||||
@code
|
@code
|
||||||
{
|
{
|
||||||
[Parameter] public Func<CreateApiKeyDto, Task> OnSubmit { get; set; }
|
[Parameter] public Func<Task> OnSubmit { get; set; }
|
||||||
|
|
||||||
private CreateApiKeyDto Request;
|
private CreateApiKeyDto Request;
|
||||||
|
|
||||||
@@ -62,7 +68,24 @@
|
|||||||
{
|
{
|
||||||
Request.Permissions = Permissions.ToArray();
|
Request.Permissions = Permissions.ToArray();
|
||||||
|
|
||||||
await OnSubmit.Invoke(Request);
|
var response = await HttpClient.PostAsJsonAsync(
|
||||||
|
"/api/admin/apiKeys",
|
||||||
|
Request,
|
||||||
|
Constants.SerializerOptions
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!response.IsSuccessStatusCode)
|
||||||
|
{
|
||||||
|
await ProblemDetailsHelper.HandleProblemDetailsAsync(response, Request, validationMessageStore);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
await ToastService.SuccessAsync(
|
||||||
|
"API Key creation",
|
||||||
|
$"Successfully created API key {Request.Name}"
|
||||||
|
);
|
||||||
|
|
||||||
|
await OnSubmit.Invoke();
|
||||||
|
|
||||||
await CloseAsync();
|
await CloseAsync();
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -1,12 +1,17 @@
|
|||||||
|
@using Moonlight.Frontend.Helpers
|
||||||
@using Moonlight.Frontend.UI.Admin.Components
|
@using Moonlight.Frontend.UI.Admin.Components
|
||||||
@using Moonlight.Shared.Http.Requests.Roles
|
@using Moonlight.Shared.Http.Requests.Roles
|
||||||
@using ShadcnBlazor.Dialogs
|
@using ShadcnBlazor.Dialogs
|
||||||
@using ShadcnBlazor.Extras.Forms
|
@using ShadcnBlazor.Extras.Forms
|
||||||
|
@using ShadcnBlazor.Extras.Toasts
|
||||||
@using ShadcnBlazor.Fields
|
@using ShadcnBlazor.Fields
|
||||||
@using ShadcnBlazor.Inputs
|
@using ShadcnBlazor.Inputs
|
||||||
|
|
||||||
@inherits ShadcnBlazor.Extras.Dialogs.DialogBase
|
@inherits ShadcnBlazor.Extras.Dialogs.DialogBase
|
||||||
|
|
||||||
|
@inject HttpClient HttpClient
|
||||||
|
@inject ToastService ToastService
|
||||||
|
|
||||||
<DialogHeader>
|
<DialogHeader>
|
||||||
<DialogTitle>
|
<DialogTitle>
|
||||||
Create new role
|
Create new role
|
||||||
@@ -49,7 +54,7 @@
|
|||||||
|
|
||||||
@code
|
@code
|
||||||
{
|
{
|
||||||
[Parameter] public Func<CreateRoleDto, Task> OnSubmit { get; set; }
|
[Parameter] public Func<Task> OnSubmit { get; set; }
|
||||||
|
|
||||||
private CreateRoleDto Request;
|
private CreateRoleDto Request;
|
||||||
private List<string> Permissions;
|
private List<string> Permissions;
|
||||||
@@ -68,7 +73,21 @@
|
|||||||
{
|
{
|
||||||
Request.Permissions = Permissions.ToArray();
|
Request.Permissions = Permissions.ToArray();
|
||||||
|
|
||||||
await OnSubmit.Invoke(Request);
|
var response = await HttpClient.PostAsJsonAsync(
|
||||||
|
"api/admin/roles",
|
||||||
|
Request,
|
||||||
|
Constants.SerializerOptions
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!response.IsSuccessStatusCode)
|
||||||
|
{
|
||||||
|
await ProblemDetailsHelper.HandleProblemDetailsAsync(response, Request, validationMessageStore);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
await ToastService.SuccessAsync("Role creation", $"Role {Request.Name} has been successfully created");
|
||||||
|
|
||||||
|
await OnSubmit.Invoke();
|
||||||
await CloseAsync();
|
await CloseAsync();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -1,11 +1,17 @@
|
|||||||
@using Moonlight.Shared.Http.Requests.Users
|
@using Moonlight.Frontend.Helpers
|
||||||
|
@using Moonlight.Shared.Http.Requests.Users
|
||||||
|
@using Moonlight.Shared.Http.Responses
|
||||||
@using ShadcnBlazor.Dialogs
|
@using ShadcnBlazor.Dialogs
|
||||||
@using ShadcnBlazor.Extras.Forms
|
@using ShadcnBlazor.Extras.Forms
|
||||||
|
@using ShadcnBlazor.Extras.Toasts
|
||||||
@using ShadcnBlazor.Fields
|
@using ShadcnBlazor.Fields
|
||||||
@using ShadcnBlazor.Inputs
|
@using ShadcnBlazor.Inputs
|
||||||
|
|
||||||
@inherits ShadcnBlazor.Extras.Dialogs.DialogBase
|
@inherits ShadcnBlazor.Extras.Dialogs.DialogBase
|
||||||
|
|
||||||
|
@inject HttpClient HttpClient
|
||||||
|
@inject ToastService ToastService
|
||||||
|
|
||||||
<DialogHeader>
|
<DialogHeader>
|
||||||
<DialogTitle>
|
<DialogTitle>
|
||||||
Create new user
|
Create new user
|
||||||
@@ -45,7 +51,7 @@
|
|||||||
|
|
||||||
@code
|
@code
|
||||||
{
|
{
|
||||||
[Parameter] public Func<CreateUserDto, Task> OnSubmit { get; set; }
|
[Parameter] public Func<Task> OnCompleted { get; set; }
|
||||||
|
|
||||||
private CreateUserDto Request;
|
private CreateUserDto Request;
|
||||||
|
|
||||||
@@ -56,7 +62,24 @@
|
|||||||
|
|
||||||
private async Task<bool> OnSubmitAsync(EditContext editContext, ValidationMessageStore validationMessageStore)
|
private async Task<bool> OnSubmitAsync(EditContext editContext, ValidationMessageStore validationMessageStore)
|
||||||
{
|
{
|
||||||
await OnSubmit.Invoke(Request);
|
var response = await HttpClient.PostAsJsonAsync(
|
||||||
|
"/api/admin/users",
|
||||||
|
Request,
|
||||||
|
Constants.SerializerOptions
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!response.IsSuccessStatusCode)
|
||||||
|
{
|
||||||
|
await ProblemDetailsHelper.HandleProblemDetailsAsync(response, Request, validationMessageStore);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
await ToastService.SuccessAsync(
|
||||||
|
"User creation",
|
||||||
|
$"Successfully created user {Request.Username}"
|
||||||
|
);
|
||||||
|
|
||||||
|
await OnCompleted.Invoke();
|
||||||
await CloseAsync();
|
await CloseAsync();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -1,14 +1,19 @@
|
|||||||
@using Moonlight.Frontend.Mappers
|
@using Moonlight.Frontend.Helpers
|
||||||
|
@using Moonlight.Frontend.Mappers
|
||||||
@using Moonlight.Frontend.UI.Admin.Components
|
@using Moonlight.Frontend.UI.Admin.Components
|
||||||
@using Moonlight.Shared.Http.Requests.ApiKeys
|
@using Moonlight.Shared.Http.Requests.ApiKeys
|
||||||
@using Moonlight.Shared.Http.Responses.ApiKeys
|
@using Moonlight.Shared.Http.Responses.ApiKeys
|
||||||
@using ShadcnBlazor.Dialogs
|
@using ShadcnBlazor.Dialogs
|
||||||
@using ShadcnBlazor.Extras.Forms
|
@using ShadcnBlazor.Extras.Forms
|
||||||
|
@using ShadcnBlazor.Extras.Toasts
|
||||||
@using ShadcnBlazor.Fields
|
@using ShadcnBlazor.Fields
|
||||||
@using ShadcnBlazor.Inputs
|
@using ShadcnBlazor.Inputs
|
||||||
|
|
||||||
@inherits ShadcnBlazor.Extras.Dialogs.DialogBase
|
@inherits ShadcnBlazor.Extras.Dialogs.DialogBase
|
||||||
|
|
||||||
|
@inject HttpClient HttpClient
|
||||||
|
@inject ToastService ToastService
|
||||||
|
|
||||||
<DialogHeader>
|
<DialogHeader>
|
||||||
<DialogTitle>Update API key</DialogTitle>
|
<DialogTitle>Update API key</DialogTitle>
|
||||||
<DialogDescription>
|
<DialogDescription>
|
||||||
@@ -45,7 +50,7 @@
|
|||||||
|
|
||||||
@code
|
@code
|
||||||
{
|
{
|
||||||
[Parameter] public Func<UpdateApiKeyDto, Task> OnSubmit { get; set; }
|
[Parameter] public Func<Task> OnSubmit { get; set; }
|
||||||
[Parameter] public ApiKeyDto Key { get; set; }
|
[Parameter] public ApiKeyDto Key { get; set; }
|
||||||
|
|
||||||
private UpdateApiKeyDto Request;
|
private UpdateApiKeyDto Request;
|
||||||
@@ -60,7 +65,25 @@
|
|||||||
private async Task<bool> OnSubmitAsync(EditContext editContext, ValidationMessageStore validationMessageStore)
|
private async Task<bool> OnSubmitAsync(EditContext editContext, ValidationMessageStore validationMessageStore)
|
||||||
{
|
{
|
||||||
Request.Permissions = Permissions.ToArray();
|
Request.Permissions = Permissions.ToArray();
|
||||||
await OnSubmit.Invoke(Request);
|
|
||||||
|
var response = await HttpClient.PatchAsJsonAsync(
|
||||||
|
$"/api/admin/apiKeys/{Key.Id}",
|
||||||
|
Request,
|
||||||
|
Constants.SerializerOptions
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!response.IsSuccessStatusCode)
|
||||||
|
{
|
||||||
|
await ProblemDetailsHelper.HandleProblemDetailsAsync(response, Request, validationMessageStore);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
await ToastService.SuccessAsync(
|
||||||
|
"API Key update",
|
||||||
|
$"Successfully updated API key {Request.Name}"
|
||||||
|
);
|
||||||
|
|
||||||
|
await OnSubmit.Invoke();
|
||||||
await CloseAsync();
|
await CloseAsync();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -1,14 +1,19 @@
|
|||||||
|
@using Moonlight.Frontend.Helpers
|
||||||
@using Moonlight.Frontend.Mappers
|
@using Moonlight.Frontend.Mappers
|
||||||
@using Moonlight.Frontend.UI.Admin.Components
|
@using Moonlight.Frontend.UI.Admin.Components
|
||||||
@using Moonlight.Shared.Http.Requests.Roles
|
@using Moonlight.Shared.Http.Requests.Roles
|
||||||
@using Moonlight.Shared.Http.Responses.Admin
|
@using Moonlight.Shared.Http.Responses.Admin
|
||||||
@using ShadcnBlazor.Dialogs
|
@using ShadcnBlazor.Dialogs
|
||||||
@using ShadcnBlazor.Extras.Forms
|
@using ShadcnBlazor.Extras.Forms
|
||||||
|
@using ShadcnBlazor.Extras.Toasts
|
||||||
@using ShadcnBlazor.Fields
|
@using ShadcnBlazor.Fields
|
||||||
@using ShadcnBlazor.Inputs
|
@using ShadcnBlazor.Inputs
|
||||||
|
|
||||||
@inherits ShadcnBlazor.Extras.Dialogs.DialogBase
|
@inherits ShadcnBlazor.Extras.Dialogs.DialogBase
|
||||||
|
|
||||||
|
@inject HttpClient HttpClient
|
||||||
|
@inject ToastService ToastService
|
||||||
|
|
||||||
<DialogHeader>
|
<DialogHeader>
|
||||||
<DialogTitle>
|
<DialogTitle>
|
||||||
Update @Role.Name
|
Update @Role.Name
|
||||||
@@ -51,7 +56,7 @@
|
|||||||
|
|
||||||
@code
|
@code
|
||||||
{
|
{
|
||||||
[Parameter] public Func<UpdateRoleDto, Task> OnSubmit { get; set; }
|
[Parameter] public Func<Task> OnSubmit { get; set; }
|
||||||
[Parameter] public RoleDto Role { get; set; }
|
[Parameter] public RoleDto Role { get; set; }
|
||||||
|
|
||||||
private UpdateRoleDto Request;
|
private UpdateRoleDto Request;
|
||||||
@@ -66,7 +71,22 @@
|
|||||||
private async Task<bool> OnSubmitAsync(EditContext editContext, ValidationMessageStore validationMessageStore)
|
private async Task<bool> OnSubmitAsync(EditContext editContext, ValidationMessageStore validationMessageStore)
|
||||||
{
|
{
|
||||||
Request.Permissions = Permissions.ToArray();
|
Request.Permissions = Permissions.ToArray();
|
||||||
await OnSubmit.Invoke(Request);
|
|
||||||
|
var response = await HttpClient.PatchAsJsonAsync(
|
||||||
|
$"api/admin/roles/{Role.Id}",
|
||||||
|
Request,
|
||||||
|
Constants.SerializerOptions
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!response.IsSuccessStatusCode)
|
||||||
|
{
|
||||||
|
await ProblemDetailsHelper.HandleProblemDetailsAsync(response, Request, validationMessageStore);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
await ToastService.SuccessAsync("Role update", $"Role {Request.Name} has been successfully updated");
|
||||||
|
|
||||||
|
await OnSubmit.Invoke();
|
||||||
await CloseAsync();
|
await CloseAsync();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -1,13 +1,19 @@
|
|||||||
@using Moonlight.Frontend.Mappers
|
@using Moonlight.Frontend.Helpers
|
||||||
|
@using Moonlight.Frontend.Mappers
|
||||||
@using Moonlight.Shared.Http.Requests.Users
|
@using Moonlight.Shared.Http.Requests.Users
|
||||||
|
@using Moonlight.Shared.Http.Responses
|
||||||
@using Moonlight.Shared.Http.Responses.Users
|
@using Moonlight.Shared.Http.Responses.Users
|
||||||
@using ShadcnBlazor.Dialogs
|
@using ShadcnBlazor.Dialogs
|
||||||
@using ShadcnBlazor.Extras.Forms
|
@using ShadcnBlazor.Extras.Forms
|
||||||
|
@using ShadcnBlazor.Extras.Toasts
|
||||||
@using ShadcnBlazor.Fields
|
@using ShadcnBlazor.Fields
|
||||||
@using ShadcnBlazor.Inputs
|
@using ShadcnBlazor.Inputs
|
||||||
|
|
||||||
@inherits ShadcnBlazor.Extras.Dialogs.DialogBase
|
@inherits ShadcnBlazor.Extras.Dialogs.DialogBase
|
||||||
|
|
||||||
|
@inject HttpClient HttpClient
|
||||||
|
@inject ToastService ToastService
|
||||||
|
|
||||||
<DialogHeader>
|
<DialogHeader>
|
||||||
<DialogTitle>
|
<DialogTitle>
|
||||||
Update @User.Username
|
Update @User.Username
|
||||||
@@ -46,7 +52,7 @@
|
|||||||
|
|
||||||
@code
|
@code
|
||||||
{
|
{
|
||||||
[Parameter] public Func<UpdateUserDto, Task> OnSubmit { get; set; }
|
[Parameter] public Func<Task> OnCompleted { get; set; }
|
||||||
[Parameter] public UserDto User { get; set; }
|
[Parameter] public UserDto User { get; set; }
|
||||||
|
|
||||||
private UpdateUserDto Request;
|
private UpdateUserDto Request;
|
||||||
@@ -58,7 +64,23 @@
|
|||||||
|
|
||||||
private async Task<bool> OnSubmitAsync(EditContext editContext, ValidationMessageStore validationMessageStore)
|
private async Task<bool> OnSubmitAsync(EditContext editContext, ValidationMessageStore validationMessageStore)
|
||||||
{
|
{
|
||||||
await OnSubmit.Invoke(Request);
|
var response = await HttpClient.PatchAsJsonAsync(
|
||||||
|
$"/api/admin/users/{User.Id}",
|
||||||
|
Request
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!response.IsSuccessStatusCode)
|
||||||
|
{
|
||||||
|
await ProblemDetailsHelper.HandleProblemDetailsAsync(response, Request, validationMessageStore);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
await ToastService.SuccessAsync(
|
||||||
|
"User update",
|
||||||
|
$"Successfully updated user {Request.Username}"
|
||||||
|
);
|
||||||
|
|
||||||
|
await OnCompleted.Invoke();
|
||||||
await CloseAsync();
|
await CloseAsync();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -123,19 +123,8 @@
|
|||||||
{
|
{
|
||||||
await DialogService.LaunchAsync<CreateApiKeyDialog>(parameters =>
|
await DialogService.LaunchAsync<CreateApiKeyDialog>(parameters =>
|
||||||
{
|
{
|
||||||
parameters[nameof(CreateApiKeyDialog.OnSubmit)] = async (CreateApiKeyDto dto) =>
|
parameters[nameof(CreateApiKeyDialog.OnSubmit)] = async () =>
|
||||||
{
|
{
|
||||||
await HttpClient.PostAsJsonAsync(
|
|
||||||
"/api/admin/apiKeys",
|
|
||||||
dto,
|
|
||||||
Constants.SerializerOptions
|
|
||||||
);
|
|
||||||
|
|
||||||
await ToastService.SuccessAsync(
|
|
||||||
"API Key creation",
|
|
||||||
$"Successfully created API key {dto.Name}"
|
|
||||||
);
|
|
||||||
|
|
||||||
await Grid.RefreshAsync();
|
await Grid.RefreshAsync();
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
@@ -146,19 +135,8 @@
|
|||||||
await DialogService.LaunchAsync<UpdateApiKeyDialog>(parameters =>
|
await DialogService.LaunchAsync<UpdateApiKeyDialog>(parameters =>
|
||||||
{
|
{
|
||||||
parameters[nameof(UpdateApiKeyDialog.Key)] = key;
|
parameters[nameof(UpdateApiKeyDialog.Key)] = key;
|
||||||
parameters[nameof(UpdateApiKeyDialog.OnSubmit)] = async (UpdateApiKeyDto dto) =>
|
parameters[nameof(UpdateApiKeyDialog.OnSubmit)] = async () =>
|
||||||
{
|
{
|
||||||
await HttpClient.PatchAsJsonAsync(
|
|
||||||
$"/api/admin/apiKeys/{key.Id}",
|
|
||||||
dto,
|
|
||||||
Constants.SerializerOptions
|
|
||||||
);
|
|
||||||
|
|
||||||
await ToastService.SuccessAsync(
|
|
||||||
"API Key update",
|
|
||||||
$"Successfully updated API key {dto.Name}"
|
|
||||||
);
|
|
||||||
|
|
||||||
await Grid.RefreshAsync();
|
await Grid.RefreshAsync();
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
@using Microsoft.AspNetCore.Authorization
|
@using Microsoft.AspNetCore.Authorization
|
||||||
@using Moonlight.Shared
|
@using Moonlight.Shared
|
||||||
@using LucideBlazor
|
@using LucideBlazor
|
||||||
|
@using Moonlight.Frontend.Helpers
|
||||||
@using Moonlight.Frontend.Services
|
@using Moonlight.Frontend.Services
|
||||||
@using Moonlight.Shared.Http.Requests.Themes
|
@using Moonlight.Shared.Http.Requests.Themes
|
||||||
@using ShadcnBlazor.Buttons
|
@using ShadcnBlazor.Buttons
|
||||||
@@ -118,12 +119,18 @@
|
|||||||
{
|
{
|
||||||
Request.CssContent = await Editor.GetValueAsync();
|
Request.CssContent = await Editor.GetValueAsync();
|
||||||
|
|
||||||
await HttpClient.PostAsJsonAsync(
|
var response = await HttpClient.PostAsJsonAsync(
|
||||||
"/api/admin/themes",
|
"/api/admin/themes",
|
||||||
Request,
|
Request,
|
||||||
Constants.SerializerOptions
|
Constants.SerializerOptions
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if (!response.IsSuccessStatusCode)
|
||||||
|
{
|
||||||
|
await ProblemDetailsHelper.HandleProblemDetailsAsync(response, Request, validationMessageStore);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
await ToastService.SuccessAsync(
|
await ToastService.SuccessAsync(
|
||||||
"Theme creation",
|
"Theme creation",
|
||||||
$"Successfully created theme {Request.Name}"
|
$"Successfully created theme {Request.Name}"
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
@using Microsoft.AspNetCore.Authorization
|
@using Microsoft.AspNetCore.Authorization
|
||||||
@using Moonlight.Shared
|
@using Moonlight.Shared
|
||||||
@using LucideBlazor
|
@using LucideBlazor
|
||||||
|
@using Moonlight.Frontend.Helpers
|
||||||
@using Moonlight.Frontend.Mappers
|
@using Moonlight.Frontend.Mappers
|
||||||
@using Moonlight.Frontend.Services
|
@using Moonlight.Frontend.Services
|
||||||
@using Moonlight.Shared.Http.Requests.Themes
|
@using Moonlight.Shared.Http.Requests.Themes
|
||||||
@@ -132,12 +133,18 @@
|
|||||||
{
|
{
|
||||||
Request.CssContent = await Editor.GetValueAsync();
|
Request.CssContent = await Editor.GetValueAsync();
|
||||||
|
|
||||||
await HttpClient.PatchAsJsonAsync(
|
var response = await HttpClient.PatchAsJsonAsync(
|
||||||
$"/api/admin/themes/{Theme.Id}",
|
$"/api/admin/themes/{Theme.Id}",
|
||||||
Request,
|
Request,
|
||||||
Constants.SerializerOptions
|
Constants.SerializerOptions
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if (!response.IsSuccessStatusCode)
|
||||||
|
{
|
||||||
|
await ProblemDetailsHelper.HandleProblemDetailsAsync(response, Request, validationMessageStore);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
await ToastService.SuccessAsync(
|
await ToastService.SuccessAsync(
|
||||||
"Theme update",
|
"Theme update",
|
||||||
$"Successfully updated theme {Request.Name}"
|
$"Successfully updated theme {Request.Name}"
|
||||||
|
|||||||
@@ -134,15 +134,8 @@
|
|||||||
{
|
{
|
||||||
await DialogService.LaunchAsync<CreateRoleDialog>(parameters =>
|
await DialogService.LaunchAsync<CreateRoleDialog>(parameters =>
|
||||||
{
|
{
|
||||||
parameters[nameof(CreateRoleDialog.OnSubmit)] = async Task (CreateRoleDto request) =>
|
parameters[nameof(CreateRoleDialog.OnSubmit)] = async Task () =>
|
||||||
{
|
{
|
||||||
await HttpClient.PostAsJsonAsync(
|
|
||||||
"api/admin/roles",
|
|
||||||
request,
|
|
||||||
Constants.SerializerOptions
|
|
||||||
);
|
|
||||||
|
|
||||||
await ToastService.SuccessAsync("Role creation", $"Role {request.Name} has been successfully created");
|
|
||||||
await Grid.RefreshAsync();
|
await Grid.RefreshAsync();
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
@@ -153,15 +146,8 @@
|
|||||||
await DialogService.LaunchAsync<UpdateRoleDialog>(parameters =>
|
await DialogService.LaunchAsync<UpdateRoleDialog>(parameters =>
|
||||||
{
|
{
|
||||||
parameters[nameof(UpdateRoleDialog.Role)] = role;
|
parameters[nameof(UpdateRoleDialog.Role)] = role;
|
||||||
parameters[nameof(UpdateRoleDialog.OnSubmit)] = async Task (UpdateRoleDto request) =>
|
parameters[nameof(UpdateRoleDialog.OnSubmit)] = async Task () =>
|
||||||
{
|
{
|
||||||
await HttpClient.PatchAsJsonAsync(
|
|
||||||
$"api/admin/roles/{role.Id}",
|
|
||||||
request,
|
|
||||||
Constants.SerializerOptions
|
|
||||||
);
|
|
||||||
|
|
||||||
await ToastService.SuccessAsync("Role update", $"Role {request.Name} has been successfully updated");
|
|
||||||
await Grid.RefreshAsync();
|
await Grid.RefreshAsync();
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -124,19 +124,8 @@
|
|||||||
{
|
{
|
||||||
await DialogService.LaunchAsync<CreateUserDialog>(parameters =>
|
await DialogService.LaunchAsync<CreateUserDialog>(parameters =>
|
||||||
{
|
{
|
||||||
parameters[nameof(CreateUserDialog.OnSubmit)] = async (CreateUserDto dto) =>
|
parameters[nameof(CreateUserDialog.OnCompleted)] = async () =>
|
||||||
{
|
{
|
||||||
await HttpClient.PostAsJsonAsync(
|
|
||||||
"/api/admin/users",
|
|
||||||
dto,
|
|
||||||
Constants.SerializerOptions
|
|
||||||
);
|
|
||||||
|
|
||||||
await ToastService.SuccessAsync(
|
|
||||||
"User creation",
|
|
||||||
$"Successfully created user {dto.Username}"
|
|
||||||
);
|
|
||||||
|
|
||||||
await Grid.RefreshAsync();
|
await Grid.RefreshAsync();
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
@@ -147,18 +136,8 @@
|
|||||||
await DialogService.LaunchAsync<UpdateUserDialog>(parameters =>
|
await DialogService.LaunchAsync<UpdateUserDialog>(parameters =>
|
||||||
{
|
{
|
||||||
parameters[nameof(UpdateUserDialog.User)] = user;
|
parameters[nameof(UpdateUserDialog.User)] = user;
|
||||||
parameters[nameof(CreateUserDialog.OnSubmit)] = async (UpdateUserDto dto) =>
|
parameters[nameof(UpdateUserDialog.OnCompleted)] = async () =>
|
||||||
{
|
{
|
||||||
await HttpClient.PatchAsJsonAsync(
|
|
||||||
$"/api/admin/users/{user.Id}",
|
|
||||||
dto
|
|
||||||
);
|
|
||||||
|
|
||||||
await ToastService.SuccessAsync(
|
|
||||||
"User update",
|
|
||||||
$"Successfully updated user {dto.Username}"
|
|
||||||
);
|
|
||||||
|
|
||||||
await Grid.RefreshAsync();
|
await Grid.RefreshAsync();
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|||||||
10
Moonlight.Shared/Http/Responses/ProblemDetails.cs
Normal file
10
Moonlight.Shared/Http/Responses/ProblemDetails.cs
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
namespace Moonlight.Shared.Http.Responses;
|
||||||
|
|
||||||
|
public class ProblemDetails
|
||||||
|
{
|
||||||
|
public string Type { get; set; }
|
||||||
|
public string Title { get; set; }
|
||||||
|
public int Status { get; set; }
|
||||||
|
public string? Detail { get; set; }
|
||||||
|
public Dictionary<string, string[]>? Errors { get; set; }
|
||||||
|
}
|
||||||
@@ -50,6 +50,9 @@ namespace Moonlight.Shared.Http;
|
|||||||
|
|
||||||
// Container Helper
|
// Container Helper
|
||||||
[JsonSerializable(typeof(ContainerHelperStatusDto))]
|
[JsonSerializable(typeof(ContainerHelperStatusDto))]
|
||||||
|
|
||||||
|
// Misc
|
||||||
|
[JsonSerializable(typeof(ProblemDetails))]
|
||||||
public partial class SerializationContext : JsonSerializerContext
|
public partial class SerializationContext : JsonSerializerContext
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user