Upgraded mooncore versions. Cleaned up code, especially startup code. Changed versions
This commit is contained in:
3
Moonlight.Client/IAssemblyMarker.cs
Normal file
3
Moonlight.Client/IAssemblyMarker.cs
Normal file
@@ -0,0 +1,3 @@
|
||||
namespace Moonlight.Client;
|
||||
|
||||
public interface IAssemblyMarker;
|
||||
@@ -7,14 +7,14 @@ namespace Moonlight.Client.Implementations;
|
||||
|
||||
public class CoreStartup : IPluginStartup
|
||||
{
|
||||
public Task BuildApplicationAsync(IServiceProvider serviceProvider, WebAssemblyHostBuilder builder)
|
||||
public void AddPlugin(WebAssemblyHostBuilder builder)
|
||||
{
|
||||
builder.Services.AddSingleton<ISidebarItemProvider, DefaultSidebarItemProvider>();
|
||||
builder.Services.AddSingleton<IOverviewElementProvider, DefaultOverviewElementProvider>();
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
public Task ConfigureApplicationAsync(IServiceProvider serviceProvider, WebAssemblyHost app)
|
||||
=> Task.CompletedTask;
|
||||
public void ConfigurePlugin(WebAssemblyHost app)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
@@ -12,7 +12,7 @@
|
||||
<PropertyGroup>
|
||||
<PackageTags>frontend</PackageTags>
|
||||
<PackageId>Moonlight.Client</PackageId>
|
||||
<Version>2.1.11</Version>
|
||||
<Version>2.1.12</Version>
|
||||
<Authors>Moonlight Panel</Authors>
|
||||
<Description>A build of the client for moonlight development</Description>
|
||||
<PackageProjectUrl>https://github.com/Moonlight-Panel/Moonlight</PackageProjectUrl>
|
||||
@@ -25,8 +25,8 @@
|
||||
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="9.0.9" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.SignalR.Client" Version="9.0.9" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="9.0.8" />
|
||||
<PackageReference Include="MoonCore" Version="2.0.1" />
|
||||
<PackageReference Include="MoonCore.Blazor.FlyonUi" Version="1.2.5" />
|
||||
<PackageReference Include="MoonCore" Version="2.0.4" />
|
||||
<PackageReference Include="MoonCore.Blazor.FlyonUi" Version="1.3.1" />
|
||||
<PackageReference Include="System.Security.Claims" Version="4.3.0" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
||||
@@ -4,6 +4,6 @@ namespace Moonlight.Client.Plugins;
|
||||
|
||||
public interface IPluginStartup
|
||||
{
|
||||
public Task BuildApplicationAsync(IServiceProvider serviceProvider, WebAssemblyHostBuilder builder);
|
||||
public Task ConfigureApplicationAsync(IServiceProvider serviceProvider, WebAssemblyHost app);
|
||||
public void AddPlugin(WebAssemblyHostBuilder builder);
|
||||
public void ConfigurePlugin(WebAssemblyHost app);
|
||||
}
|
||||
@@ -1,9 +1,7 @@
|
||||
using MoonCore.Attributes;
|
||||
using MoonCore.Helpers;
|
||||
using MoonCore.Models;
|
||||
using Moonlight.Shared.Http.Requests.Admin.Sys.Theme;
|
||||
using Moonlight.Shared.Http.Responses.Admin;
|
||||
using Moonlight.Shared.Misc;
|
||||
|
||||
namespace Moonlight.Client.Services;
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using Microsoft.AspNetCore.Components.Authorization;
|
||||
using Microsoft.AspNetCore.Components.WebAssembly.Hosting;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using MoonCore.Blazor.FlyonUi.Exceptions;
|
||||
using MoonCore.Permissions;
|
||||
@@ -7,22 +8,20 @@ using Moonlight.Client.Services;
|
||||
|
||||
namespace Moonlight.Client.Startup;
|
||||
|
||||
public partial class Startup
|
||||
public static partial class Startup
|
||||
{
|
||||
private Task RegisterAuthenticationAsync()
|
||||
private static void AddAuth(this WebAssemblyHostBuilder builder)
|
||||
{
|
||||
WebAssemblyHostBuilder.Services.AddAuthorizationCore();
|
||||
WebAssemblyHostBuilder.Services.AddCascadingAuthenticationState();
|
||||
builder.Services.AddAuthorizationCore();
|
||||
builder.Services.AddCascadingAuthenticationState();
|
||||
|
||||
WebAssemblyHostBuilder.Services.AddScoped<AuthenticationStateProvider, RemoteAuthStateProvider>();
|
||||
WebAssemblyHostBuilder.Services.AddScoped<IGlobalErrorFilter, UnauthenticatedErrorFilter>();
|
||||
builder.Services.AddScoped<AuthenticationStateProvider, RemoteAuthStateProvider>();
|
||||
builder.Services.AddScoped<IGlobalErrorFilter, UnauthenticatedErrorFilter>();
|
||||
|
||||
WebAssemblyHostBuilder.Services.AddAuthorizationPermissions(options =>
|
||||
builder.Services.AddAuthorizationPermissions(options =>
|
||||
{
|
||||
options.ClaimName = "Permissions";
|
||||
options.Prefix = "permissions:";
|
||||
});
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
}
|
||||
@@ -1,39 +1,42 @@
|
||||
using Microsoft.AspNetCore.Components.WebAssembly.Hosting;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using MoonCore.Blazor.FlyonUi;
|
||||
using MoonCore.Blazor.FlyonUi.Exceptions;
|
||||
using MoonCore.Extensions;
|
||||
using MoonCore.Helpers;
|
||||
using Moonlight.Client.Implementations;
|
||||
using Moonlight.Client.Services;
|
||||
using Moonlight.Client.UI;
|
||||
|
||||
namespace Moonlight.Client.Startup;
|
||||
|
||||
public partial class Startup
|
||||
public static partial class Startup
|
||||
{
|
||||
private Task RegisterBaseAsync()
|
||||
private static void AddBase(this WebAssemblyHostBuilder builder)
|
||||
{
|
||||
WebAssemblyHostBuilder.RootComponents.Add<App>("#app");
|
||||
WebAssemblyHostBuilder.RootComponents.Add<HeadOutlet>("head::after");
|
||||
builder.RootComponents.Add<App>("#app");
|
||||
builder.RootComponents.Add<HeadOutlet>("head::after");
|
||||
|
||||
WebAssemblyHostBuilder.Services.AddScoped(_ =>
|
||||
builder.Services.AddScoped(_ =>
|
||||
new HttpClient
|
||||
{
|
||||
BaseAddress = new Uri(Configuration.ApiUrl)
|
||||
BaseAddress = new Uri(builder.HostEnvironment.BaseAddress)
|
||||
}
|
||||
);
|
||||
|
||||
WebAssemblyHostBuilder.Services.AddScoped(sp =>
|
||||
builder.Services.AddScoped(sp =>
|
||||
{
|
||||
var httpClient = sp.GetRequiredService<HttpClient>();
|
||||
return new HttpApiClient(httpClient);
|
||||
});
|
||||
|
||||
WebAssemblyHostBuilder.Services.AddFileManagerOperations();
|
||||
WebAssemblyHostBuilder.Services.AddFlyonUiServices();
|
||||
builder.Services.AddFileManagerOperations();
|
||||
builder.Services.AddFlyonUiServices();
|
||||
|
||||
WebAssemblyHostBuilder.Services.AddScoped<ThemeService>();
|
||||
builder.Services.AddScoped<ThemeService>();
|
||||
|
||||
WebAssemblyHostBuilder.Services.AutoAddServices<Startup>();
|
||||
|
||||
return Task.CompletedTask;
|
||||
builder.Services.AutoAddServices<IAssemblyMarker>();
|
||||
|
||||
builder.Services.AddScoped<IGlobalErrorFilter, LogErrorFilter>();
|
||||
}
|
||||
}
|
||||
@@ -1,30 +1,13 @@
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using MoonCore.Blazor.FlyonUi.Exceptions;
|
||||
using Microsoft.AspNetCore.Components.WebAssembly.Hosting;
|
||||
using MoonCore.Logging;
|
||||
using Moonlight.Client.Implementations;
|
||||
|
||||
namespace Moonlight.Client.Startup;
|
||||
|
||||
public partial class Startup
|
||||
public static partial class Startup
|
||||
{
|
||||
private Task SetupLoggingAsync()
|
||||
private static void AddLogging(this WebAssemblyHostBuilder builder)
|
||||
{
|
||||
var loggerFactory = new LoggerFactory();
|
||||
|
||||
loggerFactory.AddAnsiConsole();
|
||||
|
||||
Logger = loggerFactory.CreateLogger<Startup>();
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
private Task RegisterLoggingAsync()
|
||||
{
|
||||
WebAssemblyHostBuilder.Logging.ClearProviders();
|
||||
WebAssemblyHostBuilder.Logging.AddAnsiConsole();
|
||||
|
||||
WebAssemblyHostBuilder.Services.AddScoped<IGlobalErrorFilter, LogErrorFilter>();
|
||||
|
||||
return Task.CompletedTask;
|
||||
builder.Logging.ClearProviders();
|
||||
builder.Logging.AddAnsiConsole();
|
||||
}
|
||||
}
|
||||
@@ -1,12 +1,8 @@
|
||||
using System.Text.Json;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Moonlight.Shared.Misc;
|
||||
|
||||
namespace Moonlight.Client.Startup;
|
||||
|
||||
public partial class Startup
|
||||
public static partial class Startup
|
||||
{
|
||||
private Task PrintVersionAsync()
|
||||
private static void PrintVersion()
|
||||
{
|
||||
// Fancy start console output... yes very fancy :>
|
||||
Console.Write("Running ");
|
||||
@@ -23,30 +19,5 @@ public partial class Startup
|
||||
}
|
||||
|
||||
Console.WriteLine();
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
private async Task LoadConfigurationAsync()
|
||||
{
|
||||
try
|
||||
{
|
||||
using var httpClient = new HttpClient();
|
||||
httpClient.BaseAddress = new Uri(WebAssemblyHostBuilder.HostEnvironment.BaseAddress);
|
||||
|
||||
var jsonText = await httpClient.GetStringAsync("frontend.json");
|
||||
|
||||
Configuration = JsonSerializer.Deserialize<FrontendConfiguration>(jsonText, new JsonSerializerOptions()
|
||||
{
|
||||
PropertyNameCaseInsensitive = true
|
||||
})!;
|
||||
|
||||
WebAssemblyHostBuilder.Services.AddSingleton(Configuration);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logger.LogCritical("Unable to load configuration. Unable to continue: {e}", e);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
using Microsoft.AspNetCore.Components.WebAssembly.Hosting;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using MoonCore.Logging;
|
||||
using Moonlight.Client.Plugins;
|
||||
using Moonlight.Client.Services;
|
||||
|
||||
@@ -7,72 +7,25 @@ namespace Moonlight.Client.Startup;
|
||||
|
||||
public partial class Startup
|
||||
{
|
||||
private IPluginStartup[] PluginStartups;
|
||||
private IServiceProvider PluginLoadServiceProvider;
|
||||
|
||||
private Task InitializePluginsAsync()
|
||||
private static void AddPlugins(this WebAssemblyHostBuilder builder, IPluginStartup[] startups)
|
||||
{
|
||||
// Define minimal service collection
|
||||
var startupSc = new ServiceCollection();
|
||||
|
||||
// Create logging proxy
|
||||
startupSc.AddLogging(builder =>
|
||||
foreach (var startup in startups)
|
||||
startup.AddPlugin(builder);
|
||||
|
||||
// Get all assemblies and combine them into the application assembly service
|
||||
// TODO: Consider rewriting this as it may not be that performant to do string checking to find distinct items
|
||||
builder.Services.AddSingleton(new ApplicationAssemblyService()
|
||||
{
|
||||
builder.ClearProviders();
|
||||
builder.AddAnsiConsole();
|
||||
});
|
||||
|
||||
PluginLoadServiceProvider = startupSc.BuildServiceProvider();
|
||||
|
||||
// Add application assembly service
|
||||
var appAssemblyService = new ApplicationAssemblyService();
|
||||
|
||||
appAssemblyService.Assemblies.AddRange(
|
||||
PluginStartups
|
||||
Assemblies = startups
|
||||
.Select(x => x.GetType().Assembly)
|
||||
.Distinct()
|
||||
);
|
||||
|
||||
WebAssemblyHostBuilder.Services.AddSingleton(appAssemblyService);
|
||||
|
||||
return Task.CompletedTask;
|
||||
.DistinctBy(x => x.FullName)
|
||||
.ToList()
|
||||
});
|
||||
}
|
||||
|
||||
private async Task HookPluginBuildAsync()
|
||||
private static void ConfigurePlugins(this WebAssemblyHost app, IPluginStartup[] startups)
|
||||
{
|
||||
foreach (var pluginAppStartup in PluginStartups)
|
||||
{
|
||||
try
|
||||
{
|
||||
await pluginAppStartup.BuildApplicationAsync(PluginLoadServiceProvider, WebAssemblyHostBuilder);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logger.LogError(
|
||||
"An error occured while processing 'BuildApp' for '{name}': {e}",
|
||||
pluginAppStartup.GetType().FullName,
|
||||
e
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private async Task HookPluginConfigureAsync()
|
||||
{
|
||||
foreach (var pluginAppStartup in PluginStartups)
|
||||
{
|
||||
try
|
||||
{
|
||||
await pluginAppStartup.ConfigureApplicationAsync(PluginLoadServiceProvider, WebAssemblyHost);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logger.LogError(
|
||||
"An error occured while processing 'ConfigureApp' for '{name}': {e}",
|
||||
pluginAppStartup.GetType().FullName,
|
||||
e
|
||||
);
|
||||
}
|
||||
}
|
||||
foreach (var startup in startups)
|
||||
startup.ConfigurePlugin(app);
|
||||
}
|
||||
}
|
||||
@@ -1,48 +1,22 @@
|
||||
using Microsoft.AspNetCore.Components.WebAssembly.Hosting;
|
||||
using Moonlight.Client.Plugins;
|
||||
using Moonlight.Shared.Misc;
|
||||
|
||||
namespace Moonlight.Client.Startup;
|
||||
|
||||
public partial class Startup
|
||||
public static partial class Startup
|
||||
{
|
||||
public ILogger<Startup> Logger { get; private set; }
|
||||
|
||||
// WebAssemblyHost
|
||||
public WebAssemblyHostBuilder WebAssemblyHostBuilder { get; private set; }
|
||||
public WebAssemblyHost WebAssemblyHost { get; private set; }
|
||||
|
||||
// Configuration
|
||||
public FrontendConfiguration Configuration { get; private set; }
|
||||
|
||||
|
||||
public Task InitializeAsync(IPluginStartup[]? plugins = null)
|
||||
public static void AddMoonlight(this WebAssemblyHostBuilder builder, IPluginStartup[] startups)
|
||||
{
|
||||
PluginStartups = plugins ?? [];
|
||||
|
||||
return Task.CompletedTask;
|
||||
PrintVersion();
|
||||
|
||||
builder.AddLogging();
|
||||
builder.AddBase();
|
||||
builder.AddAuth();
|
||||
builder.AddPlugins(startups);
|
||||
}
|
||||
|
||||
public async Task AddMoonlightAsync(WebAssemblyHostBuilder builder)
|
||||
public static void ConfigureMoonlight(this WebAssemblyHost app, IPluginStartup[] startups)
|
||||
{
|
||||
WebAssemblyHostBuilder = builder;
|
||||
|
||||
await PrintVersionAsync();
|
||||
|
||||
await SetupLoggingAsync();
|
||||
await LoadConfigurationAsync();
|
||||
await InitializePluginsAsync();
|
||||
|
||||
await RegisterLoggingAsync();
|
||||
await RegisterBaseAsync();
|
||||
await RegisterAuthenticationAsync();
|
||||
await HookPluginBuildAsync();
|
||||
}
|
||||
|
||||
public async Task AddMoonlightAsync(WebAssemblyHost assemblyHost)
|
||||
{
|
||||
WebAssemblyHost = assemblyHost;
|
||||
|
||||
await HookPluginConfigureAsync();
|
||||
app.ConfigurePlugins(startups);
|
||||
}
|
||||
}
|
||||
@@ -14,7 +14,6 @@
|
||||
!rounded-xs
|
||||
!text-sm
|
||||
!w-2.5
|
||||
*:[grid-area:1/1]
|
||||
*:first:rounded-tl-lg
|
||||
*:last:rounded-tr-lg
|
||||
-left-4
|
||||
@@ -43,18 +42,11 @@ alert-soft
|
||||
align-bottom
|
||||
align-middle
|
||||
animate-bounce
|
||||
animate-ping
|
||||
animate-spin
|
||||
aria-[current='page']:text-bg-soft-primary
|
||||
avatar
|
||||
avatar-placeholder
|
||||
badge
|
||||
badge-error
|
||||
badge-info
|
||||
badge-outline
|
||||
badge-primary
|
||||
badge-soft
|
||||
badge-success
|
||||
basis-full
|
||||
bg-background
|
||||
bg-background/60
|
||||
bg-base-100
|
||||
@@ -62,6 +54,7 @@ bg-base-150
|
||||
bg-base-200
|
||||
bg-base-200!
|
||||
bg-base-200/50
|
||||
bg-base-250
|
||||
bg-base-300
|
||||
bg-base-300/45
|
||||
bg-base-300/50
|
||||
@@ -157,7 +150,15 @@ disabled
|
||||
divide-base-150/60
|
||||
divide-y
|
||||
divider
|
||||
drop-shadow
|
||||
drawer
|
||||
drawer-body
|
||||
drawer-bottom
|
||||
drawer-end
|
||||
drawer-footer
|
||||
drawer-header
|
||||
drawer-start
|
||||
drawer-title
|
||||
drawer-top
|
||||
dropdown
|
||||
dropdown-active
|
||||
dropdown-disabled
|
||||
@@ -217,14 +218,13 @@ gap-y-2.5
|
||||
gap-y-3
|
||||
grid
|
||||
grid-cols-1
|
||||
grid-cols-4
|
||||
grid-flow-col
|
||||
grow
|
||||
grow-0
|
||||
h-10
|
||||
h-2
|
||||
h-3
|
||||
h-32
|
||||
h-36
|
||||
h-64
|
||||
h-8
|
||||
h-auto
|
||||
@@ -270,7 +270,6 @@ justify-center
|
||||
justify-end
|
||||
justify-start
|
||||
label-text
|
||||
leading-3
|
||||
leading-3.5
|
||||
leading-none
|
||||
left-0
|
||||
@@ -296,7 +295,6 @@ link-animated
|
||||
link-hover
|
||||
list-disc
|
||||
list-inside
|
||||
list-none
|
||||
loading
|
||||
loading-sm
|
||||
loading-spinner
|
||||
@@ -310,9 +308,10 @@ max-lg:flex-col
|
||||
max-lg:hidden
|
||||
max-md:flex-wrap
|
||||
max-md:justify-center
|
||||
max-md:w-full
|
||||
max-sm:hidden
|
||||
max-w-64
|
||||
max-w-7xl
|
||||
max-w-8
|
||||
max-w-80
|
||||
max-w-full
|
||||
max-w-lg
|
||||
@@ -323,10 +322,16 @@ mb-1
|
||||
mb-1.5
|
||||
mb-2
|
||||
mb-2.5
|
||||
mb-25
|
||||
mb-3
|
||||
mb-4
|
||||
mb-5
|
||||
md:flex
|
||||
md:gap-2
|
||||
md:hidden!
|
||||
md:items-center
|
||||
md:min-w-md
|
||||
md:navbar-end
|
||||
md:table-cell
|
||||
md:text-3xl
|
||||
me-1
|
||||
@@ -340,6 +345,7 @@ menu-disabled
|
||||
menu-dropdown
|
||||
menu-dropdown-show
|
||||
menu-horizontal
|
||||
menu-sm
|
||||
menu-title
|
||||
min-h-0
|
||||
min-h-svh
|
||||
@@ -376,9 +382,12 @@ mt-5
|
||||
mt-8
|
||||
mx-1
|
||||
mx-auto
|
||||
my-20
|
||||
my-3
|
||||
my-5
|
||||
my-auto
|
||||
navbar
|
||||
navbar-start
|
||||
object-cover
|
||||
opacity-0
|
||||
opacity-100
|
||||
@@ -392,6 +401,9 @@ overflow-x-auto
|
||||
overflow-y-auto
|
||||
overlay-open:duration-50
|
||||
overlay-open:opacity-100
|
||||
overlay-open:translate-x-0
|
||||
overlay-open:translate-y-0
|
||||
p-0
|
||||
p-0.5
|
||||
p-1
|
||||
p-1.5
|
||||
@@ -403,6 +415,7 @@ p-5
|
||||
p-6
|
||||
p-8
|
||||
pb-1
|
||||
pe-1
|
||||
pin-input
|
||||
placeholder-base-content/60
|
||||
pointer-events-auto
|
||||
@@ -427,7 +440,6 @@ py-2
|
||||
py-2.5
|
||||
py-6
|
||||
radial-progress
|
||||
radio
|
||||
range
|
||||
relative
|
||||
resize
|
||||
@@ -455,6 +467,8 @@ selected:select-active
|
||||
shadow-base-300/20
|
||||
shadow-lg
|
||||
shadow-md
|
||||
shadow-none
|
||||
shadow-sm
|
||||
shadow-xs
|
||||
shrink-0
|
||||
size-10
|
||||
@@ -462,8 +476,7 @@ size-12
|
||||
size-4
|
||||
size-5
|
||||
size-8
|
||||
skeleton
|
||||
skeleton-animated
|
||||
size-8.5
|
||||
sm:auto-cols-max
|
||||
sm:flex
|
||||
sm:items-center
|
||||
@@ -492,7 +505,6 @@ sr-only
|
||||
stack
|
||||
static
|
||||
status
|
||||
status-error
|
||||
sticky
|
||||
success-message
|
||||
switch
|
||||
@@ -548,26 +560,32 @@ tooltip
|
||||
tooltip-content
|
||||
top-0
|
||||
top-1/2
|
||||
top-3
|
||||
top-full
|
||||
transform
|
||||
transition
|
||||
transition-all
|
||||
transition-opacity
|
||||
transition-transform
|
||||
translate-x-0
|
||||
translate-x-full
|
||||
truncate
|
||||
underline
|
||||
uppercase
|
||||
validate
|
||||
w-0
|
||||
w-0.5
|
||||
w-12
|
||||
w-13
|
||||
w-20
|
||||
w-4
|
||||
w-56
|
||||
w-6
|
||||
w-64
|
||||
w-fit
|
||||
w-full
|
||||
whitespace-nowrap
|
||||
z-10
|
||||
z-1
|
||||
z-40
|
||||
z-50
|
||||
z-50
|
||||
z-69
|
||||
z-70
|
||||
@@ -64,6 +64,7 @@ badge-outline
|
||||
badge-primary
|
||||
badge-soft
|
||||
badge-success
|
||||
basis-full
|
||||
bg-background
|
||||
bg-background/60
|
||||
bg-base-100
|
||||
@@ -71,6 +72,7 @@ bg-base-150
|
||||
bg-base-200
|
||||
bg-base-200!
|
||||
bg-base-200/50
|
||||
bg-base-250
|
||||
bg-base-300
|
||||
bg-base-300/45
|
||||
bg-base-300/50
|
||||
@@ -189,6 +191,15 @@ disabled
|
||||
divide-base-150/60
|
||||
divide-y
|
||||
divider
|
||||
drawer
|
||||
drawer-body
|
||||
drawer-bottom
|
||||
drawer-end
|
||||
drawer-footer
|
||||
drawer-header
|
||||
drawer-start
|
||||
drawer-title
|
||||
drawer-top
|
||||
drop-shadow
|
||||
dropdown
|
||||
dropdown-active
|
||||
@@ -275,6 +286,7 @@ h-14
|
||||
h-2
|
||||
h-3
|
||||
h-32
|
||||
h-36
|
||||
h-6
|
||||
h-64
|
||||
h-8
|
||||
@@ -372,7 +384,9 @@ max-lg:flex-col
|
||||
max-lg:hidden
|
||||
max-md:flex-wrap
|
||||
max-md:justify-center
|
||||
max-md:w-full
|
||||
max-sm:hidden
|
||||
max-w-64
|
||||
max-w-7xl
|
||||
max-w-8
|
||||
max-w-80
|
||||
@@ -386,14 +400,20 @@ mb-1
|
||||
mb-1.5
|
||||
mb-2
|
||||
mb-2.5
|
||||
mb-25
|
||||
mb-3
|
||||
mb-4
|
||||
mb-5
|
||||
mb-8
|
||||
md:col-span-1
|
||||
md:col-span-6
|
||||
md:flex
|
||||
md:gap-2
|
||||
md:grid-cols-2
|
||||
md:hidden!
|
||||
md:items-center
|
||||
md:min-w-md
|
||||
md:navbar-end
|
||||
md:table-cell
|
||||
md:text-3xl
|
||||
me-1
|
||||
@@ -408,6 +428,7 @@ menu-dropdown
|
||||
menu-dropdown-show
|
||||
menu-focus
|
||||
menu-horizontal
|
||||
menu-sm
|
||||
menu-title
|
||||
min-h-0
|
||||
min-h-full
|
||||
@@ -452,10 +473,13 @@ mt-8
|
||||
mx-1
|
||||
mx-auto
|
||||
my-2.5
|
||||
my-20
|
||||
my-3
|
||||
my-5
|
||||
my-8
|
||||
my-auto
|
||||
navbar
|
||||
navbar-start
|
||||
object-cover
|
||||
opacity-0
|
||||
opacity-100
|
||||
@@ -470,6 +494,9 @@ overflow-x-hidden
|
||||
overflow-y-auto
|
||||
overlay-open:duration-50
|
||||
overlay-open:opacity-100
|
||||
overlay-open:translate-x-0
|
||||
overlay-open:translate-y-0
|
||||
p-0
|
||||
p-0.5
|
||||
p-1
|
||||
p-1.5
|
||||
@@ -481,6 +508,7 @@ p-5
|
||||
p-6
|
||||
p-8
|
||||
pb-1
|
||||
pe-1
|
||||
pe-1.5
|
||||
pin-input
|
||||
pin-input-underline
|
||||
@@ -548,6 +576,7 @@ shadow
|
||||
shadow-base-300/20
|
||||
shadow-lg
|
||||
shadow-md
|
||||
shadow-none
|
||||
shadow-sm
|
||||
shadow-xs
|
||||
shrink-0
|
||||
@@ -557,6 +586,7 @@ size-4
|
||||
size-5
|
||||
size-7
|
||||
size-8
|
||||
size-8.5
|
||||
skeleton
|
||||
skeleton-animated
|
||||
sm:auto-cols-max
|
||||
@@ -686,6 +716,7 @@ tooltip
|
||||
tooltip-content
|
||||
top-0
|
||||
top-1/2
|
||||
top-3
|
||||
top-full
|
||||
tracking-tight
|
||||
tracking-wide
|
||||
@@ -693,7 +724,9 @@ transform
|
||||
transition
|
||||
transition-all
|
||||
transition-opacity
|
||||
transition-transform
|
||||
translate-x-0
|
||||
translate-x-full
|
||||
truncate
|
||||
underline
|
||||
uppercase
|
||||
@@ -703,9 +736,11 @@ w-0
|
||||
w-0.5
|
||||
w-12
|
||||
w-13
|
||||
w-20
|
||||
w-32
|
||||
w-4
|
||||
w-56
|
||||
w-6
|
||||
w-64
|
||||
w-8
|
||||
w-auto
|
||||
@@ -717,4 +752,6 @@ xl:grid-cols-4
|
||||
z-1
|
||||
z-10
|
||||
z-40
|
||||
z-50
|
||||
z-50
|
||||
z-69
|
||||
z-70
|
||||
@@ -1,4 +1,5 @@
|
||||
@using Moonlight.Client.UI.Partials
|
||||
@using MoonCore.Blazor.FlyonUi.Drawers
|
||||
@using Moonlight.Client.UI.Partials
|
||||
@using MoonCore.Blazor.FlyonUi.Files.Drop
|
||||
|
||||
@inherits LayoutComponentBase
|
||||
@@ -20,6 +21,7 @@
|
||||
|
||||
<ToastLauncher/>
|
||||
<ModalLauncher/>
|
||||
<DrawerLauncher />
|
||||
|
||||
<DropHandler />
|
||||
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
@page "/admin/api"
|
||||
|
||||
@using MoonCore.Blazor.FlyonUi.Common
|
||||
@using MoonCore.Helpers
|
||||
@using MoonCore.Models
|
||||
@using Moonlight.Shared.Http.Responses.Admin.ApiKeys
|
||||
@using MoonCore.Blazor.FlyonUi.Grid
|
||||
@using MoonCore.Blazor.FlyonUi.Grid.Columns
|
||||
@using MoonCore.Blazor.FlyonUi.Grid.ToolbarItems
|
||||
@using MoonCore.Common
|
||||
|
||||
@inject HttpApiClient ApiClient
|
||||
@inject AlertService AlertService
|
||||
@@ -51,9 +52,7 @@
|
||||
|
||||
<DataGrid @ref="Grid"
|
||||
TGridItem="ApiKeyResponse"
|
||||
ItemsProvider="ItemsProviderAsync"
|
||||
EnableFiltering="true"
|
||||
EnablePagination="true">
|
||||
ItemSource="ItemSource">
|
||||
<PropertyColumn Field="x => x.Id" Sortable="true" />
|
||||
<PropertyColumn Field="x => x.Description" />
|
||||
<TemplateColumn Sortable="true" Title="Expires At">
|
||||
@@ -91,27 +90,25 @@
|
||||
@code
|
||||
{
|
||||
private DataGrid<ApiKeyResponse> Grid;
|
||||
|
||||
private async Task<DataGridItemResult<ApiKeyResponse>> ItemsProviderAsync(DataGridItemRequest request)
|
||||
{
|
||||
var query = $"?startIndex={request.StartIndex}&count={request.Count}";
|
||||
|
||||
if (!string.IsNullOrEmpty(request.SortColumn))
|
||||
private ItemSource<ApiKeyResponse> ItemSource => ItemSourceFactory.From(LoadItemsAsync);
|
||||
|
||||
private async Task<IEnumerable<ApiKeyResponse>> LoadItemsAsync(
|
||||
int startIndex, int count, string? filter, SortOption? sortOption
|
||||
)
|
||||
{
|
||||
var query = $"?startIndex={startIndex}&count={count}";
|
||||
|
||||
if (sortOption != null)
|
||||
{
|
||||
var dir = request.SortDirection == SortState.Descending ? "desc" : "asc";
|
||||
query += $"&orderBy={request.SortColumn}&orderByDir={dir}";
|
||||
var dir = sortOption.Direction == SortDirection.Descending ? "desc" : "asc";
|
||||
query += $"&orderBy={sortOption.Column}&orderByDir={dir}";
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(request.Filter))
|
||||
query += $"&filter={request.Filter}";
|
||||
if (!string.IsNullOrEmpty(filter))
|
||||
query += $"&filter={filter}";
|
||||
|
||||
var data = await ApiClient.GetJson<CountedData<ApiKeyResponse>>($"api/admin/apikeys{query}");
|
||||
|
||||
return new()
|
||||
{
|
||||
Items = data.Items,
|
||||
TotalCount = data.TotalCount
|
||||
};
|
||||
return await ApiClient.GetJson<CountedData<ApiKeyResponse>>($"api/admin/apikeys{query}");
|
||||
}
|
||||
|
||||
private async Task DeleteAsync(ApiKeyResponse apiKeyResponse)
|
||||
|
||||
@@ -2,12 +2,13 @@
|
||||
|
||||
@using System.Text.Json
|
||||
@using Microsoft.AspNetCore.Authorization
|
||||
@using MoonCore.Blazor.FlyonUi.Common
|
||||
@using MoonCore.Blazor.FlyonUi.Grid
|
||||
@using MoonCore.Blazor.FlyonUi.Grid.Columns
|
||||
@using MoonCore.Blazor.FlyonUi.Grid.ToolbarItems
|
||||
@using MoonCore.Blazor.FlyonUi.Helpers
|
||||
@using MoonCore.Common
|
||||
@using MoonCore.Helpers
|
||||
@using MoonCore.Models
|
||||
@using Moonlight.Client.Models
|
||||
@using Moonlight.Client.Services
|
||||
@using Moonlight.Shared.Http.Requests.Admin.Sys.Theme
|
||||
@@ -30,11 +31,9 @@
|
||||
|
||||
<div class="my-8">
|
||||
<DataGrid TGridItem="ThemeResponse"
|
||||
ItemsProvider="ItemsProviderAsync"
|
||||
EnableFiltering="true"
|
||||
EnablePagination="true">
|
||||
|
||||
<PropertyColumn Field="x => x.Id" Sortable="true" />
|
||||
ItemSource="ItemSource">
|
||||
|
||||
<PropertyColumn Field="x => x.Id" Sortable="true"/>
|
||||
<TemplateColumn Title="Name" Sortable="true">
|
||||
<td>
|
||||
<div class="flex items-center">
|
||||
@@ -47,9 +46,9 @@
|
||||
</div>
|
||||
</td>
|
||||
</TemplateColumn>
|
||||
<PropertyColumn Field="x => x.Version" Sortable="true" />
|
||||
<PropertyColumn Field="x => x.Author" />
|
||||
|
||||
<PropertyColumn Field="x => x.Version" Sortable="true"/>
|
||||
<PropertyColumn Field="x => x.Author"/>
|
||||
|
||||
<TemplateColumn>
|
||||
<td>
|
||||
<div class="flex justify-end">
|
||||
@@ -69,7 +68,8 @@
|
||||
</a>
|
||||
}
|
||||
|
||||
<a @onclick="() => ExportAsync(context)" @onclick:preventDefault href="#" class="flex items-center mr-2 sm:mr-3">
|
||||
<a @onclick="() => ExportAsync(context)" @onclick:preventDefault href="#"
|
||||
class="flex items-center mr-2 sm:mr-3">
|
||||
<i class="text-success icon-download me-1"></i>
|
||||
<span class="text-success">Export</span>
|
||||
</a>
|
||||
@@ -90,7 +90,7 @@
|
||||
<i class="icon-file-up"></i>
|
||||
Import
|
||||
</label>
|
||||
<InputFile OnChange="ImportAsync" id="import-theme" class="hidden" multiple />
|
||||
<InputFile OnChange="ImportAsync" id="import-theme" class="hidden" multiple/>
|
||||
<a href="/admin/system/customisation/themes/create" class="btn btn-primary">Create</a>
|
||||
</TemplateToolbarItem>
|
||||
</DataGrid>
|
||||
@@ -104,32 +104,29 @@
|
||||
@code
|
||||
{
|
||||
private DataGrid<ThemeResponse> Grid;
|
||||
|
||||
private async Task<DataGridItemResult<ThemeResponse>> ItemsProviderAsync(DataGridItemRequest request)
|
||||
{
|
||||
var query = $"?startIndex={request.StartIndex}&count={request.Count}";
|
||||
private ItemSource<ThemeResponse> ItemSource => ItemSourceFactory.From(LoadItemsAsync);
|
||||
|
||||
if (!string.IsNullOrEmpty(request.SortColumn))
|
||||
private async Task<IEnumerable<ThemeResponse>> LoadItemsAsync(
|
||||
int startIndex, int count, string? filter, SortOption? sortOption
|
||||
)
|
||||
{
|
||||
var query = $"?startIndex={startIndex}&count={count}";
|
||||
|
||||
if (sortOption != null)
|
||||
{
|
||||
var dir = request.SortDirection == SortState.Descending ? "desc" : "asc";
|
||||
query += $"&orderBy={request.SortColumn}&orderByDir={dir}";
|
||||
var dir = sortOption.Direction == SortDirection.Descending ? "desc" : "asc";
|
||||
query += $"&orderBy={sortOption.Column}&orderByDir={dir}";
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(request.Filter))
|
||||
query += $"&filter={request.Filter}";
|
||||
|
||||
var data = await ApiClient.GetJson<CountedData<ThemeResponse>>($"api/admin/system/customisation/themes{query}");
|
||||
if (!string.IsNullOrEmpty(filter))
|
||||
query += $"&filter={filter}";
|
||||
|
||||
return new()
|
||||
{
|
||||
Items = data.Items,
|
||||
TotalCount = data.TotalCount
|
||||
};
|
||||
return await ApiClient.GetJson<CountedData<ThemeResponse>>($"api/admin/system/customisation/themes{query}");
|
||||
}
|
||||
|
||||
|
||||
private async Task ImportAsync(InputFileChangeEventArgs eventArgs)
|
||||
{
|
||||
if(eventArgs.FileCount < 1)
|
||||
if (eventArgs.FileCount < 1)
|
||||
return;
|
||||
|
||||
var files = eventArgs.GetMultipleFiles();
|
||||
@@ -154,7 +151,7 @@
|
||||
|
||||
await using var stream = file.OpenReadStream(maxFileSize);
|
||||
var themeTransfer = await JsonSerializer.DeserializeAsync<ThemeTransferModel>(stream);
|
||||
|
||||
|
||||
stream.Close();
|
||||
|
||||
if (themeTransfer == null)
|
||||
@@ -174,7 +171,7 @@
|
||||
});
|
||||
|
||||
await ToastService.SuccessAsync("Successfully imported theme", theme.Name);
|
||||
|
||||
|
||||
await Grid.RefreshAsync();
|
||||
}
|
||||
catch (Exception e)
|
||||
@@ -200,7 +197,7 @@
|
||||
{
|
||||
WriteIndented = true
|
||||
});
|
||||
|
||||
|
||||
var fileName = $"{transfer.Name.Replace(" ", string.Empty).Trim()}.json";
|
||||
|
||||
await DownloadService.DownloadAsync(fileName, json);
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
@page "/admin/users"
|
||||
|
||||
@using MoonCore.Blazor.FlyonUi.Common
|
||||
@using MoonCore.Helpers
|
||||
@using MoonCore.Models
|
||||
@using Moonlight.Shared.Http.Responses.Admin.Users
|
||||
@using MoonCore.Blazor.FlyonUi.Grid
|
||||
@using MoonCore.Blazor.FlyonUi.Grid.Columns
|
||||
@using MoonCore.Common
|
||||
|
||||
@inject HttpApiClient ApiClient
|
||||
@inject AlertService AlertService
|
||||
@@ -19,14 +20,11 @@
|
||||
</div>
|
||||
|
||||
<DataGrid @ref="Grid"
|
||||
TGridItem="UserResponse"
|
||||
ItemsProvider="ItemsProviderAsync"
|
||||
EnableFiltering="true"
|
||||
EnablePagination="true">
|
||||
<PropertyColumn Field="x => x.Id" Sortable="true" />
|
||||
<PropertyColumn Field="x => x.Username" Sortable="true" />
|
||||
<PropertyColumn Field="x => x.Email" Sortable="true" />
|
||||
|
||||
ItemSource="ItemSource">
|
||||
<PropertyColumn Field="x => x.Id" Sortable="true"/>
|
||||
<PropertyColumn Field="x => x.Username" Sortable="true"/>
|
||||
<PropertyColumn Field="x => x.Email" Sortable="true"/>
|
||||
|
||||
<TemplateColumn>
|
||||
<td>
|
||||
<div class="flex justify-end">
|
||||
@@ -45,29 +43,26 @@
|
||||
@code
|
||||
{
|
||||
private DataGrid<UserResponse> Grid;
|
||||
|
||||
private async Task<DataGridItemResult<UserResponse>> ItemsProviderAsync(DataGridItemRequest request)
|
||||
{
|
||||
var query = $"?startIndex={request.StartIndex}&count={request.Count}";
|
||||
private ItemSource<UserResponse> ItemSource => ItemSourceFactory.From(LoadItemsAsync);
|
||||
|
||||
if (!string.IsNullOrEmpty(request.SortColumn))
|
||||
private async Task<IEnumerable<UserResponse>> LoadItemsAsync(
|
||||
int startIndex, int count, string? filter, SortOption? sortOption
|
||||
)
|
||||
{
|
||||
var query = $"?startIndex={startIndex}&count={count}";
|
||||
|
||||
if (sortOption != null)
|
||||
{
|
||||
var dir = request.SortDirection == SortState.Descending ? "desc" : "asc";
|
||||
query += $"&orderBy={request.SortColumn}&orderByDir={dir}";
|
||||
var dir = sortOption.Direction == SortDirection.Descending ? "desc" : "asc";
|
||||
query += $"&orderBy={sortOption.Column}&orderByDir={dir}";
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(request.Filter))
|
||||
query += $"&filter={request.Filter}";
|
||||
if (!string.IsNullOrEmpty(filter))
|
||||
query += $"&filter={filter}";
|
||||
|
||||
var data = await ApiClient.GetJson<CountedData<UserResponse>>($"api/admin/users{query}");
|
||||
|
||||
return new()
|
||||
{
|
||||
Items = data.Items,
|
||||
TotalCount = data.TotalCount
|
||||
};
|
||||
return await ApiClient.GetJson<CountedData<UserResponse>>($"api/admin/users{query}");
|
||||
}
|
||||
|
||||
|
||||
private async Task DeleteAsync(UserResponse response)
|
||||
{
|
||||
await AlertService.ConfirmDangerAsync(
|
||||
|
||||
Reference in New Issue
Block a user