Updated mooncore usage to work with the newer version

This commit is contained in:
Marcel Baumgartner
2024-05-30 13:34:24 +02:00
parent 0ff0ce1252
commit dfb633f6a7
8 changed files with 110 additions and 82 deletions

View File

@@ -1,5 +1,6 @@
using System.ComponentModel; using System.ComponentModel;
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations;
using MoonCoreUI.Attributes;
namespace Moonlight.Core.Models.Forms.Users; namespace Moonlight.Core.Models.Forms.Users;
@@ -16,5 +17,7 @@ public class UpdateUserForm
public string Email { get; set; } public string Email { get; set; }
[Description("This toggles the use of the two factor authentication")] [Description("This toggles the use of the two factor authentication")]
[RadioButtonBool("Enabled", "Disabled", TrueIcon = "bx-lock-alt", FalseIcon = "bx-lock-open-alt")]
[DisplayName("Two factor authentication")]
public bool Totp { get; set; } = false; public bool Totp { get; set; } = false;
} }

View File

@@ -17,30 +17,30 @@
<AdminUsersNavigation Index="0"/> <AdminUsersNavigation Index="0"/>
<AutoCrud TItem="User" <AutoCrud TItem="User"
TCreateForm="CreateUserForm" TCreateForm="CreateUserForm"
TUpdateForm="UpdateUserForm" TUpdateForm="UpdateUserForm"
Title="" Loader="Load"
Load="Load" CustomAdd="Add"
CustomAdd="Add" ValidateUpdate="ValidateUpdate">
ValidateUpdate="ValidateUpdate">
<View> <View>
<CrudColumn TItem="User" Field="@(x => x.Id)" Title="Id" Filterable="true"/> <CrudColumn TItem="User" Field="@(x => x.Id)" Title="Id" Filterable="true"/>
<CrudColumn TItem="User" Field="@(x => x.Email)" Title="Email" Filterable="true"/> <CrudColumn TItem="User" Field="@(x => x.Email)" Title="Email" Filterable="true"/>
<CrudColumn TItem="User" Field="@(x => x.Username)" Title="Username" Filterable="true"/> <CrudColumn TItem="User" Field="@(x => x.Username)" Title="Username" Filterable="true"/>
<CrudColumn TItem="User" Field="@(x => x.CreatedAt)" Title="Created at" /> <CrudColumn TItem="User" Field="@(x => x.CreatedAt)" Title="Created at"/>
</View> </View>
<UpdateActions> <UpdateActions>
<WButton OnClick="() => ChangePassword(context)" CssClasses="btn btn-icon btn-primary"> <WButton OnClick="() => ChangePassword(context)" CssClasses="btn btn-info me-2">
<i class="bx bx-sm bxs-key"></i> <i class="bx bx-sm bxs-key"></i>
Change password
</WButton> </WButton>
</UpdateActions> </UpdateActions>
</AutoCrud> </AutoCrud>
@code @code
{ {
private User[] Load(Repository<User> repository) private IEnumerable<User> Load(Repository<User> repository)
{ {
return repository.Get().ToArray(); return repository.Get();
} }
private async Task ChangePassword(User user) private async Task ChangePassword(User user)

View File

@@ -22,11 +22,11 @@
</Tooltip> </Tooltip>
<div class="card mt-5"> <div class="card mt-5">
<div class="card-body"> <div class="card-body px-6 py-4">
<LazyLoader Load="Load"> <LazyLoader Load="Load">
<CrudTable @ref="Table" <CrudTable @ref="Table"
TItem="Session" TItem="Session"
Items="SessionService.Sessions" ItemSource="SessionService.Sessions"
PageSize="50"> PageSize="50">
<CrudColumn TItem="Session" Title="User" Field="@(x => x.CreatedAt)"> <CrudColumn TItem="Session" Title="User" Field="@(x => x.CreatedAt)">
<Template> <Template>
@@ -63,8 +63,8 @@
<Template> <Template>
<div class="d-flex justify-content-end"> <div class="d-flex justify-content-end">
<div class="btn btn-group"> <div class="btn btn-group">
<WButton OnClick="() => Message(context)" Text="Message" CssClasses="btn btn-primary" /> <WButton OnClick="() => Message(context)" Text="Message" CssClasses="btn btn-primary"/>
<WButton OnClick="() => Redirect(context)" Text="Redirect" CssClasses="btn btn-warning" /> <WButton OnClick="() => Redirect(context)" Text="Redirect" CssClasses="btn btn-warning"/>
</div> </div>
</div> </div>
</Template> </Template>
@@ -85,9 +85,7 @@
UpdateTimer = new Timer(async _ => UpdateTimer = new Timer(async _ =>
{ {
if (Table != null) if (Table != null)
await Table.Refresh(); await Table.Refresh(isSilent: true, fullRefresh: true);
await InvokeAsync(StateHasChanged);
}, null, TimeSpan.Zero, TimeSpan.FromSeconds(1)); }, null, TimeSpan.Zero, TimeSpan.FromSeconds(1));
return Task.CompletedTask; return Task.CompletedTask;
@@ -96,10 +94,10 @@
private async Task Redirect(Session session) private async Task Redirect(Session session)
{ {
var url = await AlertService.Text("Enter the target url to redirect to"); var url = await AlertService.Text("Enter the target url to redirect to");
if(string.IsNullOrEmpty(url)) if (string.IsNullOrEmpty(url))
return; return;
try try
{ {
session.NavigationManager.NavigateTo(url); session.NavigationManager.NavigateTo(url);
@@ -111,14 +109,14 @@
await ToastService.Danger("Unable to redirect user. The user is probably no longer connect with moonlight"); await ToastService.Danger("Unable to redirect user. The user is probably no longer connect with moonlight");
} }
} }
private async Task Message(Session session) private async Task Message(Session session)
{ {
var message = await AlertService.Text("Enter the message you want to send"); var message = await AlertService.Text("Enter the message you want to send");
if(string.IsNullOrEmpty(message)) if (string.IsNullOrEmpty(message))
return; return;
try try
{ {
await session.AlertService.Info(message); await session.AlertService.Info(message);

View File

@@ -78,23 +78,53 @@ public class ServerService
var user = userRepo.Get().First(x => x.Id == form.Owner.Id); var user = userRepo.Get().First(x => x.Id == form.Owner.Id);
// Load and validate server allocations // Load and validate server allocations
ServerAllocation[] allocations = Array.Empty<ServerAllocation>(); List<ServerAllocation> allocations = new();
if (false) var amountOfAutoAllocations = image.AllocationsNeeded;
if (form.Allocations.Count > 0)
{ {
throw new DisplayException( amountOfAutoAllocations -= form.Allocations.Count;
"The dedicated ip mode has not been implemented yet. Please disable the dedicated ip option in the product configuration");
} foreach (var serverAllocation in form.Allocations) // Resolve all allocations specified in the form in the current scope
else {
{ var allocationInCurrentScope = allocationRepo.Get().First(x => x.Id == serverAllocation.Id);
allocations = allocationRepo allocations.Add(allocationInCurrentScope);
.Get() }
.FromSqlRaw(
$"SELECT * FROM `ServerAllocations` WHERE ServerId IS NULL AND ServerNodeId={node.Id} LIMIT {image.AllocationsNeeded}")
.ToArray();
} }
if (allocations.Length < 1 || allocations.Length < image.AllocationsNeeded) if (amountOfAutoAllocations > 0) // Resolve all other allocations which are required automatically
{
if (false)
{
throw new DisplayException(
"The dedicated ip mode has not been implemented yet. Please disable the dedicated ip option in the product configuration");
}
else
{
var autoAllocations = allocationRepo
.Get()
.FromSqlRaw(
$"SELECT * FROM `ServerAllocations` WHERE ServerId IS NULL AND ServerNodeId={node.Id} LIMIT {image.AllocationsNeeded + form.Allocations.Count}")
.ToArray();
var addedAutoAllocations = 0;
foreach (var autoAllocation in autoAllocations)
{
if(addedAutoAllocations >= amountOfAutoAllocations)
break;
if(form.Allocations.Any(x => x.Id == autoAllocation.Id))
continue;
allocations.Add(autoAllocation);
addedAutoAllocations++;
}
}
}
if (allocations.Count < 1 || allocations.Count < image.AllocationsNeeded)
throw new DisplayException($"Not enough free allocations found on node '{node.Name}'"); throw new DisplayException($"Not enough free allocations found on node '{node.Name}'");
// Build server db model // Build server db model

View File

@@ -33,7 +33,7 @@
<div class="card card-body mb-15 py-3 px-5"> <div class="card card-body mb-15 py-3 px-5">
@if (!Server.DisablePublicNetwork) @if (!Server.DisablePublicNetwork)
{ {
<CrudTable TItem="ServerAllocation" Items="Server.Allocations" PageSize="25" ShowPagination="false"> <CrudTable TItem="ServerAllocation" ItemSource="Server.Allocations" PageSize="25" ShowPagination="false">
<CrudColumn TItem="ServerAllocation" Field="@(x => x.IpAddress)" Title="FQDN or dedicated IP"> <CrudColumn TItem="ServerAllocation" Field="@(x => x.IpAddress)" Title="FQDN or dedicated IP">
<Template> <Template>
@if (context!.IpAddress == "0.0.0.0") @if (context!.IpAddress == "0.0.0.0")

View File

@@ -28,43 +28,43 @@
<AutoCrud TItem="ServerImage" <AutoCrud TItem="ServerImage"
TCreateForm="CreateImageForm" TCreateForm="CreateImageForm"
TUpdateForm="UpdateImageForm" TUpdateForm="UpdateImageForm"
Title="" Loader="Load"
Load="Load"
ValidateDelete="ValidateDelete" ValidateDelete="ValidateDelete"
ValidateAdd="ValidateAdd" ValidateAdd="ValidateAdd"
CustomDelete="CustomDelete" CustomDelete="CustomDelete"
@ref="Crud"> @ref="Crud">
<UpdateActions>
<a href="/admin/servers/images/view/@(context.Id)" class="btn btn-icon btn-info">
<i class="bx bx-sm bx-wrench"></i>
</a>
</UpdateActions>
<View> <View>
<CrudColumn TItem="ServerImage" Field="@(x => x.Id)" Title="Id" Filterable="true"/> <CrudColumn TItem="ServerImage" Field="@(x => x.Id)" Title="Id" Filterable="true"/>
<CrudColumn TItem="ServerImage" Field="@(x => x.Name)" Title="Name" Filterable="true"/> <CrudColumn TItem="ServerImage" Field="@(x => x.Name)" Title="Name" Filterable="true">
<Template>
<a href="/admin/servers/images/view/@context!.Id">@context.Name</a>
</Template>
</CrudColumn>
<CrudColumn TItem="ServerImage" Field="@(x => x.Author)" Title="Author" Filterable="true"/> <CrudColumn TItem="ServerImage" Field="@(x => x.Author)" Title="Author" Filterable="true"/>
<CrudColumn TItem="ServerImage"> <CrudColumn TItem="ServerImage">
<Template> <Template>
@if (!string.IsNullOrEmpty(context.UpdateUrl)) <div class="text-end">
{ @if (!string.IsNullOrEmpty(context.UpdateUrl))
<WButton CssClasses="btn btn-sm btn-info me-3"> {
<i class="bx bx-refresh"></i> <a class="me-2" href="#" @onclick:preventDefault>
Update <i class="bx bx-refresh"></i>
</WButton> Update
} </a>
}
@if (!string.IsNullOrEmpty(context.DonateUrl)) @if (!string.IsNullOrEmpty(context.DonateUrl))
{ {
<a class="btn btn-sm btn-primary me-3" href="@(context.DonateUrl)" target="_blank"> <a class="me-2" href="@(context.DonateUrl)" target="_blank">
<i class="bx bxs-heart text-danger"></i> <i class="bx bxs-heart text-danger"></i>
Donate Donate
</a>
}
<a href="#" class="me-2" @onclick:preventDefault @onclick="() => Export(context)">
<i class="bx bx-download"></i>
Export
</a> </a>
} </div>
<WButton OnClick="() => Export(context)" CssClasses="btn btn-sm btn-warning">
<i class="bx bx-download"></i>
Export
</WButton>
</Template> </Template>
</CrudColumn> </CrudColumn>
</View> </View>
@@ -93,16 +93,16 @@
private SmartCustomFileSelect ImageUpload; private SmartCustomFileSelect ImageUpload;
private SmartCustomFileSelect EggUpload; private SmartCustomFileSelect EggUpload;
private ServerImage[] Load(Repository<ServerImage> repository) private IEnumerable<ServerImage> Load(Repository<ServerImage> repository)
{ {
return repository.Get().ToArray(); return repository.Get();
} }
private Task ValidateDelete(ServerImage serverImage) private Task ValidateDelete(ServerImage serverImage)
{ {
if (ServerRepository.Get().Any(x => x.Image.Id == serverImage.Id)) if (ServerRepository.Get().Any(x => x.Image.Id == serverImage.Id))
throw new DisplayException("A server using this image exists. Please delete the servers using this image to continue"); throw new DisplayException("A server using this image exists. Please delete the servers using this image to continue");
return Task.CompletedTask; return Task.CompletedTask;
} }
@@ -123,7 +123,7 @@
return Task.CompletedTask; return Task.CompletedTask;
} }
private Task CustomDelete(ServerImage serverImage) private Task CustomDelete(ServerImage serverImage)
{ {
var image = ImageRepository var image = ImageRepository
@@ -168,7 +168,7 @@
/* this should not fail the operation */ /* this should not fail the operation */
} }
} }
ImageRepository.Delete(serverImage); ImageRepository.Delete(serverImage);
return Task.CompletedTask; return Task.CompletedTask;
@@ -216,11 +216,11 @@
await ImageUpload.RemoveSelection(); await ImageUpload.RemoveSelection();
} }
} }
private async Task ImportEgg(IBrowserFile file) private async Task ImportEgg(IBrowserFile file)
{ {
var confirm = await AlertService.YesNo("Importing pterodactyl eggs is a experimental feature and may result in unusable images. Are you sure you want to proceed?", var confirm = await AlertService.YesNo("Importing pterodactyl eggs is a experimental feature and may result in unusable images. Are you sure you want to proceed?",
"Yes, i take the risk", "Yes, i take the risk",
"Cancel"); "Cancel");
if (!confirm) if (!confirm)

View File

@@ -26,8 +26,7 @@
<AutoCrud TItem="ServerNode" <AutoCrud TItem="ServerNode"
TCreateForm="CreateNodeForm" TCreateForm="CreateNodeForm"
TUpdateForm="UpdateNodeForm" TUpdateForm="UpdateNodeForm"
Title="" Loader="LoadData"
Load="LoadData"
ValidateAdd="ValidateAdd" ValidateAdd="ValidateAdd"
ValidateUpdate="ValidateUpdate" ValidateUpdate="ValidateUpdate"
ValidateDelete="ValidateDelete"> ValidateDelete="ValidateDelete">
@@ -154,11 +153,10 @@
return Task.CompletedTask; return Task.CompletedTask;
} }
private ServerNode[] LoadData(Repository<ServerNode> repository) private IEnumerable<ServerNode> LoadData(Repository<ServerNode> repository)
{ {
return repository return repository
.Get() .Get();
.ToArray();
} }
private Task ValidateDelete(ServerNode node) private Task ValidateDelete(ServerNode node)

View File

@@ -16,7 +16,7 @@
<AutoCrud TItem="ServerNetwork" <AutoCrud TItem="ServerNetwork"
TCreateForm="CreateNetworkForm" TCreateForm="CreateNetworkForm"
TUpdateForm="UpdateNetworkForm" TUpdateForm="UpdateNetworkForm"
Load="Load" Loader="Load"
ValidateAdd="ValidateAdd"> ValidateAdd="ValidateAdd">
<View> <View>
<CrudColumn TItem="ServerNetwork" Field="@(x => x.Name)" Title="Name"/> <CrudColumn TItem="ServerNetwork" Field="@(x => x.Name)" Title="Name"/>
@@ -28,7 +28,7 @@
<CrudColumn TItem="ServerNetwork" Title="Used by"> <CrudColumn TItem="ServerNetwork" Title="Used by">
<Template> <Template>
@{ @{
var servers = UsedByCache[context.Id]; var servers = UsedByCache.ContainsKey(context.Id) ? UsedByCache[context.Id] : Array.Empty<Server>();
} }
<span> <span>
@@ -51,13 +51,12 @@
{ {
private readonly Dictionary<int, Server[]> UsedByCache = new(); private readonly Dictionary<int, Server[]> UsedByCache = new();
private ServerNetwork[] Load(Repository<ServerNetwork> repository) private IEnumerable<ServerNetwork> Load(Repository<ServerNetwork> repository)
{ {
var result = repository var result = repository
.Get() .Get()
.Include(x => x.Node) .Include(x => x.Node)
.Where(x => x.User.Id == IdentityService.CurrentUser.Id) .Where(x => x.User.Id == IdentityService.CurrentUser.Id);
.ToArray();
UsedByCache.Clear(); UsedByCache.Clear();