Restructure solution to modules structure #22
@@ -7,7 +7,7 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="10.0.3">
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="10.0.5">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
|
||||
@@ -12,8 +12,10 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="10.0.3"/>
|
||||
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="10.0.3" PrivateAssets="all"/>
|
||||
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="10.0.5" />
|
||||
<PackageReference Include="Microsoft.DotNet.HotReload.WebAssembly.Browser" Version="10.0.201" />
|
||||
<PackageReference Include="Microsoft.NET.ILLink.Tasks" Version="10.0.5" />
|
||||
<PackageReference Include="Microsoft.NET.Sdk.WebAssembly.Pack" Version="10.0.5" />
|
||||
<PackageReference Include="SimplePlugin" Version="1.0.2"/>
|
||||
<PackageReference Include="SimplePlugin.Abstractions" Version="1.0.2"/>
|
||||
</ItemGroup>
|
||||
|
||||
@@ -12,10 +12,11 @@ namespace Moonlight.Api.Admin.Users.Users;
|
||||
|
||||
public class UserAuthService
|
||||
{
|
||||
public const string CacheKeyPattern = $"Moonlight.{nameof(UserAuthService)}.{nameof(ValidateAsync)}-{{0}}";
|
||||
|
||||
private const string UserIdClaim = "UserId";
|
||||
private const string IssuedAtClaim = "IssuedAt";
|
||||
|
||||
public const string CacheKeyPattern = $"Moonlight.{nameof(UserAuthService)}.{nameof(ValidateAsync)}-{{0}}";
|
||||
private readonly IEnumerable<IUserAuthHook> Hooks;
|
||||
private readonly HybridCache HybridCache;
|
||||
private readonly ILogger<UserAuthService> Logger;
|
||||
|
||||
@@ -34,6 +34,7 @@ public class UserDeletionController : Controller
|
||||
var validationResult = await UserDeletionService.ValidateAsync(id);
|
||||
|
||||
if (!validationResult.IsValid)
|
||||
{
|
||||
return ValidationProblem(
|
||||
new ValidationProblemDetails(
|
||||
new Dictionary<string, string[]>
|
||||
@@ -45,6 +46,7 @@ public class UserDeletionController : Controller
|
||||
}
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
await UserDeletionService.DeleteAsync(id);
|
||||
return NoContent();
|
||||
|
||||
@@ -43,7 +43,9 @@ public class UsersController : Controller
|
||||
|
||||
// Filters
|
||||
if (filterOptions != null)
|
||||
{
|
||||
foreach (var filterOption in filterOptions.Filters)
|
||||
{
|
||||
query = filterOption.Key switch
|
||||
{
|
||||
nameof(Infrastructure.Database.Entities.User.Email) =>
|
||||
@@ -54,6 +56,8 @@ public class UsersController : Controller
|
||||
|
||||
_ => query
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
// Pagination
|
||||
var data = await query
|
||||
|
||||
@@ -28,7 +28,7 @@ public class DbMigrationService : IHostedLifecycleService
|
||||
|
||||
if (migrationNames.Length == 0)
|
||||
{
|
||||
Logger.LogDebug("No pending migrations found");
|
||||
Logger.LogTrace("No pending migrations found");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -24,13 +24,13 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.AspNetCore.Authentication.OpenIdConnect" Version="10.0.3"/>
|
||||
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.Server" Version="10.0.3"/>
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="10.0.3"/>
|
||||
<PackageReference Include="Microsoft.Extensions.Caching.Hybrid" Version="10.3.0"/>
|
||||
<PackageReference Include="Microsoft.Extensions.Caching.StackExchangeRedis" Version="10.0.3"/>
|
||||
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="10.0.0"/>
|
||||
<PackageReference Include="Riok.Mapperly" Version="4.3.1"/>
|
||||
<PackageReference Include="Microsoft.AspNetCore.Authentication.OpenIdConnect" Version="10.0.5" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.Server" Version="10.0.5" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="10.0.5" />
|
||||
<PackageReference Include="Microsoft.Extensions.Caching.Hybrid" Version="10.4.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Caching.StackExchangeRedis" Version="10.0.5" />
|
||||
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="10.0.1" />
|
||||
<PackageReference Include="Riok.Mapperly" Version="5.0.0-next.2" />
|
||||
<PackageReference Include="SimplePlugin.Abstractions" Version="1.0.2"/>
|
||||
<PackageReference Include="VYaml" Version="1.2.0"/>
|
||||
</ItemGroup>
|
||||
|
||||
@@ -15,7 +15,7 @@ using Moonlight.Api.Infrastructure.Helpers;
|
||||
using Moonlight.Api.Infrastructure.Hooks;
|
||||
using Moonlight.Api.Infrastructure.Implementations;
|
||||
using Moonlight.Api.Shared.Frontend;
|
||||
using SerializationContext = Moonlight.Shared.SerializationContext;
|
||||
using Moonlight.Shared;
|
||||
using VersionService = Moonlight.Api.Admin.Sys.Versions.VersionService;
|
||||
|
||||
namespace Moonlight.Api.Startup;
|
||||
|
||||
181
Moonlight.Frontend/Admin/Setup/Index.razor
Normal file
181
Moonlight.Frontend/Admin/Setup/Index.razor
Normal file
@@ -0,0 +1,181 @@
|
||||
@using LucideBlazor
|
||||
@using Moonlight.Shared.Admin.Setup
|
||||
@using ShadcnBlazor.Buttons
|
||||
@using ShadcnBlazor.Cards
|
||||
@using ShadcnBlazor.Inputs
|
||||
@using ShadcnBlazor.Labels
|
||||
@using ShadcnBlazor.Spinners
|
||||
|
||||
@inject HttpClient HttpClient
|
||||
@inject NavigationManager Navigation
|
||||
|
||||
<div class="h-screen w-full flex items-center justify-center">
|
||||
<Card ClassName="w-full max-w-[calc(100%-2rem)] lg:max-w-xl grid gap-4 p-6">
|
||||
@if (IsLoaded)
|
||||
{
|
||||
<div class="space-y-6">
|
||||
@switch (CurrentStep)
|
||||
{
|
||||
case 0:
|
||||
<div
|
||||
class="flex h-56 items-center justify-center rounded-lg bg-linear-to-br from-gray-100 to-gray-300 dark:from-gray-800 dark:to-gray-900">
|
||||
<img alt="Moonlight Logo" class="size-34" src="/_content/Moonlight.Frontend/logo.svg"/>
|
||||
</div>
|
||||
|
||||
<div class="space-y-2 text-center">
|
||||
<h2 class="text-2xl font-bold">Welcome to Moonlight Panel</h2>
|
||||
<p class="text-muted-foreground">
|
||||
You successfully installed moonlight. Now you are ready to perform some initial steps to
|
||||
complete your installation
|
||||
</p>
|
||||
</div>
|
||||
break;
|
||||
|
||||
case 1:
|
||||
<div
|
||||
class="flex h-56 items-center justify-center rounded-lg bg-linear-to-br from-gray-100 to-gray-300 dark:from-gray-800 dark:to-gray-900">
|
||||
<UserIcon ClassName="size-34 text-blue-500"/>
|
||||
</div>
|
||||
|
||||
<div class="space-y-2 text-center">
|
||||
<h2 class="text-2xl font-bold">Admin Account Creation</h2>
|
||||
<p class="text-muted-foreground">
|
||||
To continue please fill in the account details of the user you want to use as the initial
|
||||
administrator account.
|
||||
If you use an external OIDC provider, these details need to match with your desired OIDC
|
||||
account
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="grid grid-cols-1 gap-5">
|
||||
<div class="grid gap-2">
|
||||
<Label for="username">Username</Label>
|
||||
<TextInputField
|
||||
@bind-Value="SetupDto.AdminUsername"
|
||||
id="username"
|
||||
placeholder="someoneelse"/>
|
||||
</div>
|
||||
<div class="grid gap-2">
|
||||
<Label for="email">Email</Label>
|
||||
<TextInputField
|
||||
@bind-Value="SetupDto.AdminEmail"
|
||||
id="email"
|
||||
Type="email"
|
||||
placeholder="a@cool.email"/>
|
||||
</div>
|
||||
<div class="grid gap-2">
|
||||
<Label for="password">Password</Label>
|
||||
<TextInputField
|
||||
@bind-Value="SetupDto.AdminPassword"
|
||||
id="password"
|
||||
Type="password"
|
||||
placeholder="......."/>
|
||||
</div>
|
||||
</div>
|
||||
break;
|
||||
|
||||
case 2:
|
||||
<div
|
||||
class="flex h-56 items-center justify-center rounded-lg bg-linear-to-br from-gray-100 to-gray-300 dark:from-gray-800 dark:to-gray-900">
|
||||
<RocketIcon ClassName="size-34 text-blue-500"/>
|
||||
</div>
|
||||
|
||||
<div class="space-y-2 text-center">
|
||||
<h2 class="text-2xl font-bold">You are all set!</h2>
|
||||
<p class="text-muted-foreground">
|
||||
You are now ready to finish the initial setup.
|
||||
The configured options will be applied to the instance.
|
||||
You will be redirected to the login after changes have been applied successfully
|
||||
</p>
|
||||
</div>
|
||||
break;
|
||||
}
|
||||
|
||||
<div class="flex items-center justify-between">
|
||||
<div class="flex gap-2">
|
||||
@for (var step = 0; step < StepCount; step++)
|
||||
{
|
||||
if (step == CurrentStep)
|
||||
{
|
||||
<div class="h-2 w-2 rounded-full transition-colors bg-foreground">
|
||||
</div>
|
||||
}
|
||||
else
|
||||
{
|
||||
<div class="h-2 w-2 rounded-full transition-colors bg-muted">
|
||||
</div>
|
||||
}
|
||||
}
|
||||
</div>
|
||||
<div class="flex gap-1.5">
|
||||
@if (CurrentStep > 0)
|
||||
{
|
||||
<Button @onclick="() => Navigate(-1)" Variant="ButtonVariant.Outline">
|
||||
<ChevronLeftIcon/>
|
||||
Back
|
||||
</Button>
|
||||
}
|
||||
else if (CurrentStep != StepCount - 1)
|
||||
{
|
||||
<Button @onclick="() => Navigate(1)">
|
||||
Continue
|
||||
<ArrowRightIcon/>
|
||||
</Button>
|
||||
}
|
||||
else
|
||||
{
|
||||
<Button @onclick="ApplyAsync">
|
||||
Finish
|
||||
<RocketIcon/>
|
||||
</Button>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
else
|
||||
{
|
||||
<div class="w-full flex justify-center items-center">
|
||||
<Spinner ClassName="size-10"/>
|
||||
</div>
|
||||
}
|
||||
</Card>
|
||||
</div>
|
||||
|
||||
@code
|
||||
{
|
||||
private bool IsLoaded;
|
||||
|
||||
private int CurrentStep;
|
||||
private readonly int StepCount = 3;
|
||||
|
||||
private readonly ApplySetupDto SetupDto = new();
|
||||
|
||||
private void Navigate(int diff)
|
||||
{
|
||||
CurrentStep += diff;
|
||||
}
|
||||
|
||||
protected override async Task OnAfterRenderAsync(bool firstRender)
|
||||
{
|
||||
if (!firstRender)
|
||||
return;
|
||||
|
||||
var response = await HttpClient.GetAsync("api/admin/setup");
|
||||
|
||||
if (!response.IsSuccessStatusCode)
|
||||
{
|
||||
Navigation.NavigateTo("/", true);
|
||||
return;
|
||||
}
|
||||
|
||||
IsLoaded = true;
|
||||
await InvokeAsync(StateHasChanged);
|
||||
}
|
||||
|
||||
private async Task ApplyAsync()
|
||||
{
|
||||
await HttpClient.PostAsJsonAsync("api/admin/setup", SetupDto);
|
||||
Navigation.NavigateTo("/", true);
|
||||
}
|
||||
}
|
||||
@@ -1,177 +0,0 @@
|
||||
@using LucideBlazor
|
||||
@using Moonlight.Shared.Admin.Setup
|
||||
@using ShadcnBlazor.Buttons
|
||||
@using ShadcnBlazor.Cards
|
||||
@using ShadcnBlazor.Inputs
|
||||
@using ShadcnBlazor.Labels
|
||||
@using ShadcnBlazor.Spinners
|
||||
@inject HttpClient HttpClient
|
||||
@inject NavigationManager Navigation
|
||||
|
||||
<div class="h-screen w-full flex items-center justify-center">
|
||||
<Card ClassName="w-full max-w-[calc(100%-2rem)] lg:max-w-xl grid gap-4 p-6">
|
||||
@if (IsLoaded)
|
||||
{
|
||||
<div class="space-y-6">
|
||||
@if (CurrentStep == 0)
|
||||
{
|
||||
<div
|
||||
class="flex h-56 items-center justify-center rounded-lg bg-linear-to-br from-gray-100 to-gray-300 dark:from-gray-800 dark:to-gray-900">
|
||||
<img alt="Moonlight Logo" class="size-34" src="/_content/Moonlight.Frontend/logo.svg"/>
|
||||
</div>
|
||||
|
||||
<div class="space-y-2 text-center">
|
||||
<h2 class="text-2xl font-bold">Welcome to Moonlight Panel</h2>
|
||||
<p class="text-muted-foreground">
|
||||
You successfully installed moonlight. Now you are ready to perform some initial steps to
|
||||
complete your installation
|
||||
</p>
|
||||
</div>
|
||||
}
|
||||
else if (CurrentStep == 1)
|
||||
{
|
||||
<div
|
||||
class="flex h-56 items-center justify-center rounded-lg bg-linear-to-br from-gray-100 to-gray-300 dark:from-gray-800 dark:to-gray-900">
|
||||
<UserIcon ClassName="size-34 text-blue-500"/>
|
||||
</div>
|
||||
|
||||
<div class="space-y-2 text-center">
|
||||
<h2 class="text-2xl font-bold">Admin Account Creation</h2>
|
||||
<p class="text-muted-foreground">
|
||||
To continue please fill in the account details of the user you want to use as the initial
|
||||
administrator account.
|
||||
If you use an external OIDC provider, these details need to match with your desired OIDC
|
||||
account
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="grid grid-cols-1 gap-5">
|
||||
<div class="grid gap-2">
|
||||
<Label for="username">Username</Label>
|
||||
<TextInputField
|
||||
@bind-Value="SetupDto.AdminUsername"
|
||||
id="username"
|
||||
placeholder="someoneelse"/>
|
||||
</div>
|
||||
<div class="grid gap-2">
|
||||
<Label for="email">Email</Label>
|
||||
<TextInputField
|
||||
@bind-Value="SetupDto.AdminEmail"
|
||||
id="email"
|
||||
Type="email"
|
||||
placeholder="a@cool.email"/>
|
||||
</div>
|
||||
<div class="grid gap-2">
|
||||
<Label for="password">Password</Label>
|
||||
<TextInputField
|
||||
@bind-Value="SetupDto.AdminPassword"
|
||||
id="password"
|
||||
Type="password"
|
||||
placeholder="......."/>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
else if (CurrentStep == 2)
|
||||
{
|
||||
<div
|
||||
class="flex h-56 items-center justify-center rounded-lg bg-linear-to-br from-gray-100 to-gray-300 dark:from-gray-800 dark:to-gray-900">
|
||||
<RocketIcon ClassName="size-34 text-blue-500"/>
|
||||
</div>
|
||||
|
||||
<div class="space-y-2 text-center">
|
||||
<h2 class="text-2xl font-bold">You are all set!</h2>
|
||||
<p class="text-muted-foreground">
|
||||
You are now ready to finish the initial setup.
|
||||
The configured options will be applied to the instance.
|
||||
You will be redirected to the login after changes have been applied successfully
|
||||
</p>
|
||||
</div>
|
||||
}
|
||||
<div class="flex items-center justify-between">
|
||||
<div class="flex gap-2">
|
||||
@for (var step = 0; step < StepCount; step++)
|
||||
{
|
||||
if (step == CurrentStep)
|
||||
{
|
||||
<div class="h-2 w-2 rounded-full transition-colors bg-foreground">
|
||||
</div>
|
||||
}
|
||||
else
|
||||
{
|
||||
<div class="h-2 w-2 rounded-full transition-colors bg-muted">
|
||||
</div>
|
||||
}
|
||||
}
|
||||
</div>
|
||||
<div class="flex gap-1.5">
|
||||
@if (CurrentStep > 0)
|
||||
{
|
||||
<Button @onclick="() => Navigate(-1)" Variant="ButtonVariant.Outline">
|
||||
<ChevronLeftIcon/>
|
||||
Back
|
||||
</Button>
|
||||
}
|
||||
@if (CurrentStep != StepCount - 1)
|
||||
{
|
||||
<Button @onclick="() => Navigate(1)">
|
||||
Continue
|
||||
<ArrowRightIcon/>
|
||||
</Button>
|
||||
}
|
||||
else
|
||||
{
|
||||
<Button @onclick="ApplyAsync">
|
||||
Finish
|
||||
<RocketIcon/>
|
||||
</Button>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
else
|
||||
{
|
||||
<div class="w-full flex justify-center items-center">
|
||||
<Spinner ClassName="size-10"/>
|
||||
</div>
|
||||
}
|
||||
</Card>
|
||||
</div>
|
||||
|
||||
@code
|
||||
{
|
||||
private bool IsLoaded;
|
||||
|
||||
private int CurrentStep;
|
||||
private readonly int StepCount = 3;
|
||||
|
||||
private readonly ApplySetupDto SetupDto = new();
|
||||
|
||||
private void Navigate(int diff)
|
||||
{
|
||||
CurrentStep += diff;
|
||||
}
|
||||
|
||||
protected override async Task OnAfterRenderAsync(bool firstRender)
|
||||
{
|
||||
if (!firstRender)
|
||||
return;
|
||||
|
||||
var response = await HttpClient.GetAsync("api/admin/setup");
|
||||
|
||||
if (!response.IsSuccessStatusCode)
|
||||
{
|
||||
Navigation.NavigateTo("/", true);
|
||||
return;
|
||||
}
|
||||
|
||||
IsLoaded = true;
|
||||
await InvokeAsync(StateHasChanged);
|
||||
}
|
||||
|
||||
private async Task ApplyAsync()
|
||||
{
|
||||
await HttpClient.PostAsJsonAsync("api/admin/setup", SetupDto);
|
||||
Navigation.NavigateTo("/", true);
|
||||
}
|
||||
}
|
||||
@@ -59,7 +59,7 @@
|
||||
|
||||
private CreateApiKeyDto Request;
|
||||
|
||||
private readonly List<string> Permissions = new();
|
||||
private readonly List<string> Permissions = [];
|
||||
|
||||
protected override void OnInitialized()
|
||||
{
|
||||
@@ -88,7 +88,7 @@
|
||||
}
|
||||
|
||||
await ToastService.SuccessAsync(
|
||||
"API Key creation",
|
||||
"API Key Creation",
|
||||
$"Successfully created API key {Request.Name}"
|
||||
);
|
||||
|
||||
|
||||
@@ -12,7 +12,6 @@
|
||||
@using ShadcnBlazor.Extras.Dialogs
|
||||
@using ShadcnBlazor.Extras.Toasts
|
||||
@using ShadcnBlazor.Tabels
|
||||
@using SerializationContext = Moonlight.Shared.SerializationContext
|
||||
|
||||
@inject ToastService ToastService
|
||||
@inject DialogService DialogService
|
||||
|
||||
@@ -84,7 +84,7 @@
|
||||
}
|
||||
|
||||
await ToastService.SuccessAsync(
|
||||
"API Key update",
|
||||
"API Key Update",
|
||||
$"Successfully updated API key {Request.Name}"
|
||||
);
|
||||
|
||||
|
||||
@@ -122,10 +122,10 @@
|
||||
|
||||
@code
|
||||
{
|
||||
private ContainerHelperStatusDto StatusDto;
|
||||
private string SelectedVersion = "v2.1";
|
||||
private bool NoBuildCache;
|
||||
|
||||
private ContainerHelperStatusDto StatusDto;
|
||||
private VersionDto[] Versions;
|
||||
|
||||
private async Task LoadAsync(LazyLoader _)
|
||||
@@ -1,15 +1,16 @@
|
||||
@inherits ShadcnBlazor.Extras.Dialogs.DialogBase
|
||||
@using System.Text.Json
|
||||
@using LucideBlazor
|
||||
@using Moonlight.Shared
|
||||
@using Moonlight.Shared.Admin.Sys.ContainerHelper
|
||||
@using ShadcnBlazor.Buttons
|
||||
@using ShadcnBlazor.Dialogs
|
||||
@using ShadcnBlazor.Progresses
|
||||
@using ShadcnBlazor.Spinners
|
||||
@using SerializationContext = Moonlight.Shared.SerializationContext
|
||||
|
||||
@inject HttpClient HttpClient
|
||||
|
||||
@inherits ShadcnBlazor.Extras.Dialogs.DialogBase
|
||||
|
||||
<DialogHeader>
|
||||
<DialogTitle>
|
||||
Updating instance to @Version...
|
||||
@@ -10,6 +10,7 @@
|
||||
@using ShadcnBlazor.Emptys
|
||||
@using ShadcnBlazor.Extras.Common
|
||||
@using ShadcnBlazor.Spinners
|
||||
|
||||
@inject HttpClient HttpClient
|
||||
@inject IAuthorizationService AuthorizationService
|
||||
|
||||
|
||||
@@ -2,8 +2,6 @@
|
||||
@using LucideBlazor
|
||||
@using Microsoft.AspNetCore.Authorization
|
||||
@using Microsoft.AspNetCore.Components.Authorization
|
||||
@using Moonlight.Frontend.Admin.Sys.HelperContainer
|
||||
@using Moonlight.Frontend.Admin.Sys.Settings
|
||||
@using Moonlight.Shared
|
||||
@using ShadcnBlazor.Tab
|
||||
|
||||
@@ -36,7 +34,7 @@
|
||||
@if (SettingsResult.Succeeded)
|
||||
{
|
||||
<TabsContent Value="settings">
|
||||
<Settings/>
|
||||
<<Moonlight.Frontend.Admin.Sys.Settings.Index/>
|
||||
</TabsContent>
|
||||
}
|
||||
@if (DiagnoseResult.Succeeded)
|
||||
@@ -60,7 +58,7 @@
|
||||
@if (InstanceResult.Succeeded && VersionsResult.Succeeded)
|
||||
{
|
||||
<TabsContent Value="instance">
|
||||
<Instance/>
|
||||
<Moonlight.Frontend.Admin.Sys.ContainerHelper.Index/>
|
||||
</TabsContent>
|
||||
}
|
||||
</Tabs>
|
||||
|
||||
@@ -1,15 +1,14 @@
|
||||
@page "/admin"
|
||||
|
||||
@using LucideBlazor
|
||||
@using Moonlight.Frontend.Infrastructure.Helpers
|
||||
@using Moonlight.Shared
|
||||
@using Moonlight.Shared.Admin.Sys
|
||||
@using ShadcnBlazor.Buttons
|
||||
@using ShadcnBlazor.Cards
|
||||
@using ShadcnBlazor.Extras.Dialogs
|
||||
@using ShadcnBlazor.Spinners
|
||||
@using SerializationContext = Moonlight.Shared.SerializationContext
|
||||
|
||||
@inject HttpClient HttpClient
|
||||
@inject DialogService DialogService
|
||||
|
||||
<h1 class="text-xl font-semibold">Overview</h1>
|
||||
<div class="text-muted-foreground">
|
||||
|
||||
@@ -5,21 +5,28 @@ namespace Moonlight.Frontend.Admin.Sys.Settings;
|
||||
|
||||
public class SystemSettingsOptions
|
||||
{
|
||||
private readonly List<SystemSettingsPage> InnerComponents = new();
|
||||
public IReadOnlyList<SystemSettingsPage> Components => InnerComponents;
|
||||
|
||||
private readonly List<SystemSettingsPage> InnerComponents = [];
|
||||
|
||||
public void Add<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] TIcon,
|
||||
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)]
|
||||
TComponent>(string name, string description,
|
||||
int order)
|
||||
where TIcon : ComponentBase where TComponent : ComponentBase
|
||||
int order
|
||||
) where TIcon : ComponentBase where TComponent : ComponentBase
|
||||
{
|
||||
Add(name, description, order, typeof(TIcon), typeof(TComponent));
|
||||
}
|
||||
|
||||
public void Add(string name, string description, int order,
|
||||
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] Type iconComponent,
|
||||
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] Type component)
|
||||
public void Add(
|
||||
string name,
|
||||
string description,
|
||||
int order,
|
||||
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)]
|
||||
Type iconComponent,
|
||||
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)]
|
||||
Type component
|
||||
)
|
||||
{
|
||||
InnerComponents.Add(new SystemSettingsPage(name, description, order, iconComponent, component));
|
||||
}
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
@using LucideBlazor
|
||||
@using Moonlight.Frontend.Infrastructure.Helpers
|
||||
@using Moonlight.Frontend.Shared.Frontend
|
||||
@using Moonlight.Shared
|
||||
@using Moonlight.Shared.Admin.Sys.Settings
|
||||
@using ShadcnBlazor.Extras.Common
|
||||
@using ShadcnBlazor.Extras.Forms
|
||||
@using ShadcnBlazor.Extras.Toasts
|
||||
@using ShadcnBlazor.Fields
|
||||
@using ShadcnBlazor.Inputs
|
||||
@using SerializationContext = Moonlight.Shared.SerializationContext
|
||||
|
||||
@inject HttpClient HttpClient
|
||||
@inject ToastService ToastService
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
@page "/admin/system/themes/create"
|
||||
|
||||
@using LucideBlazor
|
||||
@using Microsoft.AspNetCore.Authorization
|
||||
@using Moonlight.Frontend.Infrastructure.Helpers
|
||||
@@ -13,7 +14,6 @@
|
||||
@using ShadcnBlazor.Fields
|
||||
@using ShadcnBlazor.Inputs
|
||||
@using ShadcnBlazor.Switches
|
||||
@using SerializationContext = Moonlight.Shared.SerializationContext
|
||||
|
||||
@attribute [Authorize(Policy = Permissions.Themes.Create)]
|
||||
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
@using ShadcnBlazor.Extras.AlertDialogs
|
||||
@using ShadcnBlazor.Extras.Toasts
|
||||
@using ShadcnBlazor.Tabels
|
||||
@using SerializationContext = Moonlight.Shared.SerializationContext
|
||||
|
||||
@inject ToastService ToastService
|
||||
@inject NavigationManager Navigation
|
||||
@@ -142,20 +141,11 @@
|
||||
return new DataGridResponse<ThemeDto>(response!.Data, response.TotalLength);
|
||||
}
|
||||
|
||||
private void Create()
|
||||
{
|
||||
Navigation.NavigateTo("/admin/system/themes/create");
|
||||
}
|
||||
private void Create() => Navigation.NavigateTo("/admin/system/themes/create");
|
||||
|
||||
private void Edit(ThemeDto theme)
|
||||
{
|
||||
Navigation.NavigateTo($"/admin/system/themes/{theme.Id}");
|
||||
}
|
||||
private void Edit(ThemeDto theme) => Navigation.NavigateTo($"/admin/system/themes/{theme.Id}");
|
||||
|
||||
private void Download(ThemeDto theme)
|
||||
{
|
||||
Navigation.NavigateTo($"api/admin/themes/{theme.Id}/export", true);
|
||||
}
|
||||
private void Download(ThemeDto theme) => Navigation.NavigateTo($"api/admin/themes/{theme.Id}/export", true);
|
||||
|
||||
private async Task DeleteAsync(ThemeDto theme)
|
||||
{
|
||||
|
||||
@@ -7,7 +7,7 @@ namespace Moonlight.Frontend.Admin.Sys.Themes;
|
||||
[Mapper]
|
||||
[SuppressMessage("Mapper", "RMG020:No members are mapped in an object mapping")]
|
||||
[SuppressMessage("Mapper", "RMG012:No members are mapped in an object mapping")]
|
||||
public partial class ThemeMapper
|
||||
public static partial class ThemeMapper
|
||||
{
|
||||
public static partial UpdateThemeDto ToUpdate(ThemeDto theme);
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
@page "/admin/system/themes/{Id:int}"
|
||||
|
||||
@using LucideBlazor
|
||||
@using Microsoft.AspNetCore.Authorization
|
||||
@using Moonlight.Frontend.Infrastructure.Helpers
|
||||
@@ -14,7 +15,6 @@
|
||||
@using ShadcnBlazor.Fields
|
||||
@using ShadcnBlazor.Inputs
|
||||
@using ShadcnBlazor.Switches
|
||||
@using SerializationContext = Moonlight.Shared.SerializationContext
|
||||
|
||||
@attribute [Authorize(Policy = Permissions.Themes.Edit)]
|
||||
|
||||
|
||||
@@ -22,10 +22,10 @@
|
||||
</TabsTrigger>
|
||||
</TabsList>
|
||||
<TabsContent Value="users">
|
||||
<Users/>
|
||||
<Moonlight.Frontend.Admin.Users.Users.Index/>
|
||||
</TabsContent>
|
||||
<TabsContent Value="roles">
|
||||
<Roles/>
|
||||
<Moonlight.Frontend.Admin.Users.Roles.Index/>
|
||||
</TabsContent>
|
||||
</Tabs>
|
||||
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
@using Moonlight.Frontend.Admin.Users.Shared
|
||||
@using Moonlight.Frontend.Infrastructure.Helpers
|
||||
@using Moonlight.Shared
|
||||
@using Moonlight.Shared.Admin.Users.Roles
|
||||
@using ShadcnBlazor.Dialogs
|
||||
@using ShadcnBlazor.Extras.Forms
|
||||
@using ShadcnBlazor.Extras.Toasts
|
||||
@using ShadcnBlazor.Fields
|
||||
@using ShadcnBlazor.Inputs
|
||||
@using SerializationContext = Moonlight.Shared.SerializationContext
|
||||
|
||||
@inherits ShadcnBlazor.Extras.Dialogs.DialogBase
|
||||
|
||||
@@ -67,7 +67,7 @@
|
||||
Permissions = []
|
||||
};
|
||||
|
||||
Permissions = new List<string>();
|
||||
Permissions = [];
|
||||
}
|
||||
|
||||
private async Task<bool> OnSubmitAsync(EditContext editContext, ValidationMessageStore validationMessageStore)
|
||||
@@ -86,7 +86,7 @@
|
||||
return false;
|
||||
}
|
||||
|
||||
await ToastService.SuccessAsync("Role creation", $"Role {Request.Name} has been successfully created");
|
||||
await ToastService.SuccessAsync("Role Creation", $"Role {Request.Name} has been successfully created");
|
||||
|
||||
await OnSubmit.Invoke();
|
||||
await CloseAsync();
|
||||
|
||||
@@ -11,7 +11,6 @@
|
||||
@using ShadcnBlazor.Extras.Dialogs
|
||||
@using ShadcnBlazor.Extras.Toasts
|
||||
@using ShadcnBlazor.Tabels
|
||||
@using SerializationContext = Moonlight.Shared.SerializationContext
|
||||
|
||||
@inject HttpClient HttpClient
|
||||
@inject DialogService DialogService
|
||||
@@ -1,4 +1,5 @@
|
||||
@using LucideBlazor
|
||||
@using Moonlight.Shared
|
||||
@using Moonlight.Shared.Admin.Users.Roles
|
||||
@using Moonlight.Shared.Admin.Users.Users
|
||||
@using Moonlight.Shared.Shared
|
||||
@@ -9,10 +10,11 @@
|
||||
@using ShadcnBlazor.Extras.Common
|
||||
@using ShadcnBlazor.Labels
|
||||
@using ShadcnBlazor.Tabels
|
||||
@inherits ShadcnBlazor.Extras.Dialogs.DialogBase
|
||||
|
||||
@inject HttpClient HttpClient
|
||||
|
||||
@inherits ShadcnBlazor.Extras.Dialogs.DialogBase
|
||||
|
||||
<DialogHeader>
|
||||
<DialogTitle>
|
||||
Manage members of @Role.Name
|
||||
@@ -75,7 +77,8 @@
|
||||
query += $"&searchTerm={request.SearchTerm}";
|
||||
|
||||
var response = await HttpClient.GetFromJsonAsync<PagedData<UserDto>>(
|
||||
$"api/admin/roles/{Role.Id}/members{query}"
|
||||
$"api/admin/roles/{Role.Id}/members{query}",
|
||||
SerializationContext.Default.Options
|
||||
);
|
||||
|
||||
return new DataGridResponse<UserDto>(response!.Data, response.TotalLength);
|
||||
@@ -89,7 +92,8 @@
|
||||
query += $"&searchTerm={searchTerm}";
|
||||
|
||||
var response = await HttpClient.GetFromJsonAsync<PagedData<UserDto>>(
|
||||
$"api/admin/roles/{Role.Id}/members/available{query}"
|
||||
$"api/admin/roles/{Role.Id}/members/available{query}",
|
||||
SerializationContext.Default.Options
|
||||
);
|
||||
|
||||
return response!.Data;
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
@using Moonlight.Frontend.Admin.Users.Shared
|
||||
@using Moonlight.Frontend.Infrastructure.Helpers
|
||||
@using Moonlight.Shared
|
||||
@using Moonlight.Shared.Admin.Users.Roles
|
||||
@using ShadcnBlazor.Dialogs
|
||||
@using ShadcnBlazor.Extras.Forms
|
||||
@using ShadcnBlazor.Extras.Toasts
|
||||
@using ShadcnBlazor.Fields
|
||||
@using ShadcnBlazor.Inputs
|
||||
@using SerializationContext = Moonlight.Shared.SerializationContext
|
||||
|
||||
@inherits ShadcnBlazor.Extras.Dialogs.DialogBase
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
@using ShadcnBlazor.Checkboxes
|
||||
@using ShadcnBlazor.Extras.Common
|
||||
@using ShadcnBlazor.Labels
|
||||
|
||||
@inject IEnumerable<IPermissionProvider> Providers
|
||||
|
||||
<LazyLoader Load="LoadAsync">
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
@using Moonlight.Frontend.Infrastructure.Helpers
|
||||
@using Moonlight.Shared
|
||||
@using Moonlight.Shared.Admin.Users.Users
|
||||
@using ShadcnBlazor.Dialogs
|
||||
@using ShadcnBlazor.Extras.Forms
|
||||
@using ShadcnBlazor.Extras.Toasts
|
||||
@using ShadcnBlazor.Fields
|
||||
@using ShadcnBlazor.Inputs
|
||||
@using SerializationContext = Moonlight.Shared.SerializationContext
|
||||
|
||||
@inject ToastService ToastService
|
||||
@inject HttpClient HttpClient
|
||||
|
||||
@inherits ShadcnBlazor.Extras.Dialogs.DialogBase
|
||||
|
||||
@inject HttpClient HttpClient
|
||||
@inject ToastService ToastService
|
||||
|
||||
<DialogHeader>
|
||||
<DialogTitle>
|
||||
Create new user
|
||||
|
||||
@@ -11,7 +11,6 @@
|
||||
@using ShadcnBlazor.Extras.Dialogs
|
||||
@using ShadcnBlazor.Extras.Toasts
|
||||
@using ShadcnBlazor.Tabels
|
||||
@using SerializationContext = Moonlight.Shared.SerializationContext
|
||||
|
||||
@inject HttpClient HttpClient
|
||||
@inject AlertDialogService AlertDialogService
|
||||
@@ -1,4 +1,5 @@
|
||||
@using Moonlight.Frontend.Infrastructure.Helpers
|
||||
@using Moonlight.Shared
|
||||
@using Moonlight.Shared.Admin.Users.Users
|
||||
@using ShadcnBlazor.Dialogs
|
||||
@using ShadcnBlazor.Extras.Forms
|
||||
@@ -62,7 +63,8 @@
|
||||
{
|
||||
var response = await HttpClient.PatchAsJsonAsync(
|
||||
$"/api/admin/users/{User.Id}",
|
||||
Request
|
||||
Request,
|
||||
SerializationContext.Default.Options
|
||||
);
|
||||
|
||||
if (!response.IsSuccessStatusCode)
|
||||
|
||||
@@ -3,8 +3,8 @@ using System.Net.Http.Json;
|
||||
using System.Security.Claims;
|
||||
using Microsoft.AspNetCore.Components.Authorization;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Moonlight.Shared;
|
||||
using Moonlight.Shared.Shared.Auth;
|
||||
using SerializationContext = Moonlight.Shared.SerializationContext;
|
||||
|
||||
namespace Moonlight.Frontend.Infrastructure.Services;
|
||||
|
||||
|
||||
@@ -21,9 +21,9 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.AspNetCore.Components.Authorization" Version="10.0.3"/>
|
||||
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="10.0.3"/>
|
||||
<PackageReference Include="Riok.Mapperly" Version="4.3.1"/>
|
||||
<PackageReference Include="Microsoft.AspNetCore.Components.Authorization" Version="10.0.5" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="10.0.5" />
|
||||
<PackageReference Include="Riok.Mapperly" Version="5.0.0-next.2" />
|
||||
<PackageReference Include="ShadcnBlazor" Version="1.0.14"/>
|
||||
<PackageReference Include="ShadcnBlazor.Extras" Version="1.0.14"/>
|
||||
<PackageReference Include="SimplePlugin.Abstractions" Version="1.0.2"/>
|
||||
@@ -54,8 +54,6 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<AdditionalFiles Include="Admin\Sys\HelperContainer\Instance.razor"/>
|
||||
<AdditionalFiles Include="Admin\Sys\Settings\Settings.razor"/>
|
||||
<AdditionalFiles Include="Admin\Sys\Themes\Create.razor"/>
|
||||
<AdditionalFiles Include="Admin\Sys\Themes\Index.razor"/>
|
||||
<AdditionalFiles Include="Admin\Sys\Themes\Update.razor"/>
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
@using Moonlight.Shared.Shared.Auth
|
||||
@using Moonlight.Shared
|
||||
@using Moonlight.Shared.Shared.Auth
|
||||
@using ShadcnBlazor.Buttons
|
||||
@using ShadcnBlazor.Cards
|
||||
@using ShadcnBlazor.Spinners
|
||||
@using SerializationContext = Moonlight.Shared.SerializationContext
|
||||
|
||||
@inject HttpClient HttpClient
|
||||
@inject NavigationManager Navigation
|
||||
|
||||
Reference in New Issue
Block a user