Merge branch 'v2' into v2_ImprovedAdminPage

This commit is contained in:
Masu Baumgartner 2024-05-18 22:14:05 +02:00 committed by GitHub
commit 158115bb3b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
14 changed files with 167 additions and 28 deletions

View file

@ -33,7 +33,7 @@ body:
attributes: attributes:
label: Panel Version label: Panel Version
description: Version number of your Panel (latest is not a version) description: Version number of your Panel (latest is not a version)
placeholder: 1.4.0 placeholder: v2 EA
validations: validations:
required: true required: true
@ -42,16 +42,7 @@ body:
attributes: attributes:
label: Daemon Version label: Daemon Version
description: Version number of your Daemon (latest is not a version) description: Version number of your Daemon (latest is not a version)
placeholder: 1.4.2 placeholder: v2 EA
validations:
required: true
- type: input
id: wings-version
attributes:
label: Wings Version
description: Version number of your Wings (latest is not a version)
placeholder: 1.4.2
validations: validations:
required: true required: true
@ -93,4 +84,4 @@ body:
- label: I have provided all relevant details, including the specific game and Docker images I am using if this issue is related to running a server. - label: I have provided all relevant details, including the specific game and Docker images I am using if this issue is related to running a server.
required: true required: true
- label: I have checked in the Discord server and believe this is a bug with the software, and not a configuration issue with my specific system. - label: I have checked in the Discord server and believe this is a bug with the software, and not a configuration issue with my specific system.
required: true required: true

3
.gitignore vendored
View file

@ -400,4 +400,5 @@ FodyWeavers.xsd
storage/ storage/
.idea/.idea.Moonlight/.idea/dataSources.xml .idea/.idea.Moonlight/.idea/dataSources.xml
Moonlight/wwwroot/css/theme.css Moonlight/wwwroot/css/theme.css
Moonlight/wwwroot/css/theme.css.map Moonlight/wwwroot/css/theme.css.map
.idea/.idea.Moonlight/.idea/discord.xml

View file

@ -7,7 +7,7 @@
@inherits ErrorBoundaryBase @inherits ErrorBoundaryBase
@if (Crashed || CurrentException != null) @if (Crashed || Exception != null)
{ {
if (Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") == "Development" || (IdentityService.IsLoggedIn && IdentityService.CurrentUser.Permissions >= 9000)) if (Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") == "Development" || (IdentityService.IsLoggedIn && IdentityService.CurrentUser.Permissions >= 9000))
{ {

View file

@ -11,14 +11,14 @@
else else
{ {
<div class="row"> <div class="row">
<div class="col-3 text-center d-flex align-items-center"> <div class="col-auto text-center d-flex align-items-center px-5">
<i class="bx bx-lg text-white align-middle @(Icon)"></i> <i class="bx bx-lg text-white align-middle @(Icon)"></i>
</div> </div>
<div class="col-9"> <div class="col">
<div class="fw-semibold text-primary fs-2"> <div class="fw-semibold text-primary fs-2">
@Value @Value
</div> </div>
<div class="fs-4 mt-2"> <div class="fs-4 mt-2 text-white">
@Description @Description
</div> </div>
</div> </div>

View file

@ -34,7 +34,7 @@
private async Task Load(LazyLoader arg) private async Task Load(LazyLoader arg)
{ {
await arg.SetText("Loading Information..."); await arg.SetText("Loading statistics...");
var componentImplementations = await PluginService.GetImplementations<IAdminDashboardComponent>(); var componentImplementations = await PluginService.GetImplementations<IAdminDashboardComponent>();

View file

@ -54,9 +54,12 @@ public class FileManagerFeature : MoonlightFeature
await pluginService.RegisterImplementation<IFileManagerContextAction>(new RenameContextAction()); await pluginService.RegisterImplementation<IFileManagerContextAction>(new RenameContextAction());
await pluginService.RegisterImplementation<IFileManagerContextAction>(new MoveContextAction()); await pluginService.RegisterImplementation<IFileManagerContextAction>(new MoveContextAction());
await pluginService.RegisterImplementation<IFileManagerContextAction>(new DownloadContextAction()); await pluginService.RegisterImplementation<IFileManagerContextAction>(new DownloadContextAction());
await pluginService.RegisterImplementation<IFileManagerContextAction>(new ArchiveContextAction());
await pluginService.RegisterImplementation<IFileManagerContextAction>(new ExtractContextAction());
await pluginService.RegisterImplementation<IFileManagerContextAction>(new DeleteContextAction()); await pluginService.RegisterImplementation<IFileManagerContextAction>(new DeleteContextAction());
await pluginService.RegisterImplementation<IFileManagerSelectionAction>(new MoveSelectionAction()); await pluginService.RegisterImplementation<IFileManagerSelectionAction>(new MoveSelectionAction());
await pluginService.RegisterImplementation<IFileManagerSelectionAction>(new ArchiveSelectionAction());
await pluginService.RegisterImplementation<IFileManagerSelectionAction>(new DeleteSelectionAction()); await pluginService.RegisterImplementation<IFileManagerSelectionAction>(new DeleteSelectionAction());
await pluginService.RegisterImplementation<IFileManagerCreateAction>(new CreateFileAction()); await pluginService.RegisterImplementation<IFileManagerCreateAction>(new CreateFileAction());

View file

@ -0,0 +1,59 @@
using MoonCore.Exceptions;
using MoonCore.Helpers;
using MoonCoreUI.Services;
using Moonlight.Features.FileManager.Interfaces;
using Moonlight.Features.FileManager.Models.Abstractions.FileAccess;
namespace Moonlight.Features.FileManager.Implementations;
public class ArchiveContextAction : IFileManagerContextAction
{
public string Name => "Archive";
public string Icon => "bxs-archive-in";
public string Color => "warning";
public Func<FileEntry, bool> Filter => _ => true;
public async Task Execute(BaseFileAccess access, UI.Components.FileManager fileManager, FileEntry entry,
IServiceProvider provider)
{
var archiveAccess = access.Actions as IArchiveFileActions;
if (archiveAccess == null)
throw new DisplayException("This file access does not support archiving");
var alertService = provider.GetRequiredService<AlertService>();
var fileName = await alertService.Text("Enter the archive file name", "",
Formatter.FormatDate(DateTime.UtcNow) + ".tar.gz");
if (string.IsNullOrEmpty(fileName) || fileName.Contains("..")) // => canceled
return;
var toastService = provider.GetRequiredService<ToastService>();
await toastService.CreateProgress("fileManagerArchive", "Archiving... Please be patient");
try
{
await archiveAccess.Archive(
access.CurrentDirectory + fileName,
new[] { access.CurrentDirectory + entry.Name }
);
await toastService.Success("Successfully created archive");
}
catch (Exception e)
{
Logger.Warn($"An error occured while archiving item ({entry.Name}):");
Logger.Warn(e);
await toastService.Danger("An unknown error occured while creating archive");
}
finally
{
await toastService.RemoveProgress("fileManagerArchive");
}
await fileManager.View.Refresh();
}
}

View file

@ -14,10 +14,7 @@ public class ArchiveSelectionAction : IFileManagerSelectionAction
public async Task Execute(BaseFileAccess access, UI.Components.FileManager fileManager, FileEntry[] entries, public async Task Execute(BaseFileAccess access, UI.Components.FileManager fileManager, FileEntry[] entries,
IServiceProvider provider) IServiceProvider provider)
{ {
if (!access.Actions.GetType().IsAssignableFrom(typeof(IArchiveFileActions))) var archiveAccess = access.Actions as IArchiveFileActions;
throw new DisplayException("This file access does not support archiving");
var archiveAccess = access as IArchiveFileActions;
if (archiveAccess == null) if (archiveAccess == null)
throw new DisplayException("This file access does not support archiving"); throw new DisplayException("This file access does not support archiving");
@ -29,10 +26,30 @@ public class ArchiveSelectionAction : IFileManagerSelectionAction
if (string.IsNullOrEmpty(fileName) || fileName.Contains("..")) // => canceled if (string.IsNullOrEmpty(fileName) || fileName.Contains("..")) // => canceled
return; return;
var toastService = provider.GetRequiredService<ToastService>();
await archiveAccess.Archive( await toastService.CreateProgress("fileManagerArchive", "Archiving... Please be patient");
access.CurrentDirectory + fileName,
entries.Select(x => access.CurrentDirectory + x.Name).ToArray() try
); {
await archiveAccess.Archive(
access.CurrentDirectory + fileName,
entries.Select(x => access.CurrentDirectory + x.Name).ToArray()
);
await toastService.Success("Successfully created archive");
}
catch (Exception e)
{
Logger.Warn($"An error occured while archiving items ({entries.Length}):");
Logger.Warn(e);
await toastService.Danger("An unknown error occured while creating archive");
}
finally
{
await toastService.RemoveProgress("fileManagerArchive");
}
} }
} }

View file

@ -0,0 +1,52 @@
using MoonCore.Exceptions;
using MoonCore.Helpers;
using MoonCoreUI.Services;
using Moonlight.Features.FileManager.Interfaces;
using Moonlight.Features.FileManager.Models.Abstractions.FileAccess;
namespace Moonlight.Features.FileManager.Implementations;
public class ExtractContextAction : IFileManagerContextAction
{
public string Name => "Extract";
public string Icon => "bxs-archive-out";
public string Color => "warning";
public Func<FileEntry, bool> Filter => entry => entry.IsFile && entry.Name.EndsWith(".tar.gz");
public async Task Execute(BaseFileAccess access, UI.Components.FileManager fileManager, FileEntry entry, IServiceProvider provider)
{
var archiveAccess = access.Actions as IArchiveFileActions;
if (archiveAccess == null)
throw new DisplayException("This file access does not support archiving");
await fileManager.OpenFolderSelect("Select where you want to extract the content of the archive", async destination =>
{
var toastService = provider.GetRequiredService<ToastService>();
await toastService.CreateProgress("fileManagerExtract", "Extracting... Please be patient");
try
{
await archiveAccess.Extract(
access.CurrentDirectory + entry.Name,
destination
);
await toastService.Success("Successfully extracted archive");
}
catch (Exception e)
{
Logger.Warn($"An error occured while extracting archive ({entry.Name}):");
Logger.Warn(e);
await toastService.Danger("An unknown error occured while extracting archive");
}
finally
{
await toastService.RemoveProgress("fileManagerExtract");
}
await fileManager.View.Refresh();
});
}
}

View file

@ -3,4 +3,5 @@ namespace Moonlight.Features.FileManager.Models.Abstractions.FileAccess;
public interface IArchiveFileActions public interface IArchiveFileActions
{ {
public Task Archive(string path, string[] files); public Task Archive(string path, string[] files);
public Task Extract(string path, string destination);
} }

View file

@ -95,7 +95,8 @@ else
OnEntryClicked="OnEntryClicked" OnEntryClicked="OnEntryClicked"
OnNavigateUpClicked="OnNavigateUpClicked" OnNavigateUpClicked="OnNavigateUpClicked"
OnSelectionChanged="OnSelectionChanged" OnSelectionChanged="OnSelectionChanged"
EnableContextMenu="true"> EnableContextMenu="true"
ShowUploadPrompt="true">
<ContextMenuTemplate> <ContextMenuTemplate>
@foreach (var action in ContextActions) @foreach (var action in ContextActions)
{ {

View file

@ -210,7 +210,7 @@
</tbody> </tbody>
</table> </table>
@if (Entries.Length == 0) @if (Entries.Length == 0 && ShowUploadPrompt)
{ {
<div class="py-4"> <div class="py-4">
<IconAlert Color="primary" Title="No files and folders found" Icon="bx-cloud-upload"> <IconAlert Color="primary" Title="No files and folders found" Icon="bx-cloud-upload">
@ -240,6 +240,7 @@
[Parameter] public bool ShowDate { get; set; } = true; [Parameter] public bool ShowDate { get; set; } = true;
[Parameter] public bool ShowSelect { get; set; } = true; [Parameter] public bool ShowSelect { get; set; } = true;
[Parameter] public bool ShowNavigateUp { get; set; } = true; [Parameter] public bool ShowNavigateUp { get; set; } = true;
[Parameter] public bool ShowUploadPrompt { get; set; } = false;
[Parameter] public RenderFragment<FileEntry>? ContextMenuTemplate { get; set; } [Parameter] public RenderFragment<FileEntry>? ContextMenuTemplate { get; set; }
[Parameter] public bool EnableContextMenu { get; set; } = false; [Parameter] public bool EnableContextMenu { get; set; } = false;

View file

@ -47,6 +47,11 @@ public class ServerApiFileActions : IFileActions, IArchiveFileActions
{ {
await ApiClient.Post($"archive?path={path}&provider=tar.gz", files); await ApiClient.Post($"archive?path={path}&provider=tar.gz", files);
} }
public async Task Extract(string path, string destination)
{
await ApiClient.Post($"extract?path={path}&destination={destination}&provider=tar.gz");
}
public IFileActions Clone() => new ServerApiFileActions(Endpoint, Token, ServerId); public IFileActions Clone() => new ServerApiFileActions(Endpoint, Token, ServerId);

View file

@ -13,11 +13,13 @@
@using MoonCore.Exceptions @using MoonCore.Exceptions
@using Moonlight.Features.Servers.Configuration @using Moonlight.Features.Servers.Configuration
@using MoonCore.Services @using MoonCore.Services
@using Moonlight.Core.Services
@inject Repository<Server> ServerRepository @inject Repository<Server> ServerRepository
@inject ServerService ServerService @inject ServerService ServerService
@inject ToastService ToastService @inject ToastService ToastService
@inject AlertService AlertService @inject AlertService AlertService
@inject IdentityService IdentityService
@inject ConfigService<ServersConfiguration> ConfigService @inject ConfigService<ServersConfiguration> ConfigService
@implements IDisposable @implements IDisposable
@ -217,6 +219,12 @@
.Include(x => x.Owner) .Include(x => x.Owner)
.First(x => x.Id == Id); .First(x => x.Id == Id);
if (Server.Owner.Id != IdentityService.CurrentUser.Id && IdentityService.CurrentUser.Permissions < 5000)
{
Server = null!;
return;
}
await lazyLoader.SetText("Establishing a connection to the server"); await lazyLoader.SetText("Establishing a connection to the server");
// Create console wrapper // Create console wrapper