diff --git a/Moonlight/Features/Servers/Entities/Server.cs b/Moonlight/Features/Servers/Entities/Server.cs index 7377987a..b25d0d94 100644 --- a/Moonlight/Features/Servers/Entities/Server.cs +++ b/Moonlight/Features/Servers/Entities/Server.cs @@ -14,14 +14,14 @@ public class Server public string? OverrideStartupCommand { get; set; } - public int Cpu { get; set; } + public int Cpu { get; set; } = 100; public int Memory { get; set; } public int Disk { get; set; } - public bool UseVirtualDisk { get; set; } + public bool UseVirtualDisk { get; set; } = false; public ServerNode Node { get; set; } public ServerNetwork? Network { get; set; } - public bool DisablePublicNetwork { get; set; } + public bool DisablePublicNetwork { get; set; } = false; public ServerAllocation MainAllocation { get; set; } public List Allocations { get; set; } = new(); diff --git a/Moonlight/Features/Servers/UI/Views/Admin/Index.razor b/Moonlight/Features/Servers/UI/Views/Admin/Index.razor index 75aab3af..965fd648 100644 --- a/Moonlight/Features/Servers/UI/Views/Admin/Index.razor +++ b/Moonlight/Features/Servers/UI/Views/Admin/Index.razor @@ -1,33 +1,36 @@ @page "/admin/servers" +@using System.ComponentModel.DataAnnotations @using Moonlight.Features.Servers.UI.Components @using Microsoft.EntityFrameworkCore @using MoonCore.Abstractions +@using MoonCore.Blazor.Extensions +@using MoonCore.Blazor.Forms.Fast.Components +@using MoonCore.Blazor.Models.Fast @using MoonCore.Exceptions +@using Moonlight.Core.Database.Entities @using Moonlight.Features.Servers.Entities @using Moonlight.Features.Servers.Models.Enums -@using Moonlight.Features.Servers.Models.Forms.Admin.Servers @using Moonlight.Features.Servers.Services @inject ServerService ServerService @inject Repository ServerRepository +@inject Repository AllocRepository @inject ToastService ToastService +@inject AlertService AlertService @inject ILogger Logger @attribute [RequirePermission(5000)] -@* - + + @@ -47,56 +50,17 @@ - - - Create a new server in order to manage it using this page. Need help? Check out our documentation - - -*@ + + + + Force delete + + + @code { - /* - private void OnConfigure(AutoCrudOptions options) - { - options.AddCustomItemLoader("FreeAllocations", LoadFreeAllocations); - - options.AddCustomDisplayFunction("AllocationWithIp", - allocation => allocation.IpAddress + ":" + allocation.Port); - }*/ - - private IEnumerable Load(Repository repository) - { - return repository - .Get() - .Include(x => x.Owner) - .Include(x => x.Image) - .Include(x => x.Allocations) - .Include(x => x.Node); - } - - private IEnumerable LoadFreeAllocations(Repository repository, Server? currentServer) - { - if (currentServer == null) - { - return repository - .Get() - .FromSqlRaw("SELECT * FROM `ServerAllocations` WHERE ServerId IS NULL"); - } - else - { - return currentServer.Allocations.Concat( - repository - .Get() - .FromSqlRaw($"SELECT * FROM `ServerAllocations` WHERE ServerId IS NULL AND ServerNodeId = {currentServer.Node.Id}") - .AsEnumerable() // => executes the sql - ); - } - } - - private async Task CustomAdd(Server form) => await ServerService.Create(form); - - private async Task CustomDelete(Server s) => await ServerService.Delete(s); + private FastCrud Crud; private async Task CustomUpdate(Server server) { @@ -154,4 +118,138 @@ return Task.CompletedTask; } + + private async Task StartForceDelete(Server server) + { + await AlertService.Confirm( + "Confirm forcefully server deletion", + "Do you really want to delete this server forcefully?", + async () => + { + await ServerService.Delete(server, safeDelete: false); + await ToastService.Success("Successfully deleted server"); + + await Crud.SetState(FastCrudState.View); + } + ); + } + + private IEnumerable Loader(Repository repository) + { + return repository + .Get() + .Include(x => x.Image) + .Include(x => x.Node) + .Include(x => x.Owner) + .Include(x => x.Allocations); + } + + private void OnConfigure(FastCrudConfiguration configuration) + { + configuration.CustomCreate = ServerService.Create; + configuration.CustomDelete = server => ServerService.Delete(server); + configuration.CustomEdit = CustomUpdate; + + configuration.ValidateEdit = ValidateUpdate; + } + + // Shared form + private void OnConfigureBase(FastConfiguration configuration, Server server) + { + configuration.AddProperty(x => x.Name) + .WithDefaultComponent() + .WithValidation(FastValidators.Required); + + Func usernameFunc = x => x.Username; + + configuration.AddProperty(x => x.Owner) + .WithComponent>() + .WithAdditionalOption("SearchFunc", usernameFunc) + .WithAdditionalOption("DisplayFunc", usernameFunc) + .WithValidation(FastValidators.Required); + + Func imageNameFunc = x => x.Name; + + configuration.AddProperty(x => x.Image) + .WithComponent>() + .WithAdditionalOption("SearchFunc", imageNameFunc) + .WithAdditionalOption("DisplayFunc", imageNameFunc) + .WithValidation(FastValidators.Required); + + configuration.AddProperty(x => x.Cpu) + .WithDefaultComponent() + .WithValidation(x => x > 0 ? ValidationResult.Success : new("You need to provide a valid value")) + .WithSection("Resources", "bxs-chip") + .WithDescription("The cores the server will be able to use. 100 = 1 Core"); + + configuration.AddProperty(x => x.Memory) + .WithComponent() + .WithAdditionalOption("MinimumUnit", "MB") + .WithAdditionalOption("DefaultUnit", "GB") + .WithValidation(x => x > 0 ? ValidationResult.Success : new("You need to provide a valid value")) + .WithSection("Resources") + .WithDescription("The amount of memory this server will be able to use"); + + configuration.AddProperty(x => x.Disk) + .WithComponent() + .WithAdditionalOption("MinimumUnit", "MB") + .WithAdditionalOption("DefaultUnit", "GB") + .WithValidation(x => x > 0 ? ValidationResult.Success : new("You need to provide a valid value")) + .WithSection("Resources") + .WithDescription("The amount of disk space this server will be able to use"); + + Func nodeNameFunc = x => x.Name; + + configuration.AddProperty(x => x.Node) + .WithComponent>() + .WithAdditionalOption("SearchFunc", nodeNameFunc) + .WithAdditionalOption("DisplayFunc", nodeNameFunc) + .WithValidation(FastValidators.Required); + + configuration.AddProperty(x => x.UseVirtualDisk) + .WithComponent() + .WithPage("Advanced options") + .WithDescription("Whether to use a virtual disk for storing server files. Dont use this if you want to overallocate as the virtual disks will fill out the space you allocate"); + + configuration.AddProperty(x => x.DisablePublicNetwork) + .WithComponent() + .WithPage("Network") + .WithDescription("Whether to block all incoming connections to this server from the internet"); + } + + // Specific form + private void OnConfigureCreate(FastConfiguration configuration, Server server) + { + OnConfigureBase(configuration, server); + + // Allocations + var items = AllocRepository + .Get() + .FromSqlRaw("SELECT * FROM `ServerAllocations` WHERE ServerId IS NULL") + .AsEnumerable(); + + Func buildDisplay = x => $"{x.IpAddress}:{x.Port}"; + + configuration.AddProperty(x => x.Allocations) + .WithMultiSelect(buildDisplay, buildDisplay, items) + .WithPage("Network"); + } + + private void OnConfigureEdit(FastConfiguration configuration, Server server) + { + OnConfigureBase(configuration, server); + + // Allocations + var items = server.Allocations.Concat( + AllocRepository + .Get() + .FromSqlRaw($"SELECT * FROM `ServerAllocations` WHERE ServerId IS NULL AND ServerNodeId = {server.Node.Id}") + .AsEnumerable()); + + Func buildDisplay = x => $"{x.IpAddress}:{x.Port}"; + + configuration.AddProperty(x => x.Allocations) + .WithMultiSelect(buildDisplay, buildDisplay, items) + .WithPage("Network"); + } } \ No newline at end of file diff --git a/Moonlight/Moonlight.csproj b/Moonlight/Moonlight.csproj index b180b0ea..41cc40cc 100644 --- a/Moonlight/Moonlight.csproj +++ b/Moonlight/Moonlight.csproj @@ -94,7 +94,7 @@ runtime; build; native; contentfiles; analyzers; buildtransitive - +