Implemented website order
This commit is contained in:
@@ -4,7 +4,7 @@ namespace Moonlight.App.Models.Forms;
|
|||||||
|
|
||||||
public class WebsiteDataModel
|
public class WebsiteDataModel
|
||||||
{
|
{
|
||||||
[Required(ErrorMessage = "You need a domain")]
|
[Required(ErrorMessage = "You need to enter a domain")]
|
||||||
[RegularExpression(@"([a-z0-9|-]+\.)*[a-z0-9|-]+\.[a-z]+", ErrorMessage = "You need to enter a valid domain")]
|
[RegularExpression(@"([a-z0-9|-]+\.)*[a-z0-9|-]+\.[a-z]+", ErrorMessage = "You need to enter a valid domain")]
|
||||||
public string BaseDomain { get; set; } = "";
|
public string BaseDomain { get; set; } = "";
|
||||||
}
|
}
|
||||||
10
Moonlight/App/Models/Forms/WebsiteOrderDataModel.cs
Normal file
10
Moonlight/App/Models/Forms/WebsiteOrderDataModel.cs
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
|
||||||
|
namespace Moonlight.App.Models.Forms;
|
||||||
|
|
||||||
|
public class WebsiteOrderDataModel
|
||||||
|
{
|
||||||
|
[Required(ErrorMessage = "You need to enter a domain")]
|
||||||
|
[RegularExpression(@"([a-z0-9|-]+\.)*[a-z0-9|-]+\.[a-z]+", ErrorMessage = "You need to enter a valid domain")]
|
||||||
|
public string BaseDomain { get; set; } = "";
|
||||||
|
}
|
||||||
@@ -6,12 +6,18 @@ namespace Moonlight.App.Services;
|
|||||||
public class SmartDeployService
|
public class SmartDeployService
|
||||||
{
|
{
|
||||||
private readonly NodeRepository NodeRepository;
|
private readonly NodeRepository NodeRepository;
|
||||||
|
private readonly PleskServerRepository PleskServerRepository;
|
||||||
|
private readonly WebsiteService WebsiteService;
|
||||||
private readonly NodeService NodeService;
|
private readonly NodeService NodeService;
|
||||||
|
|
||||||
public SmartDeployService(NodeRepository nodeRepository, NodeService nodeService)
|
public SmartDeployService(
|
||||||
|
NodeRepository nodeRepository,
|
||||||
|
NodeService nodeService, PleskServerRepository pleskServerRepository, WebsiteService websiteService)
|
||||||
{
|
{
|
||||||
NodeRepository = nodeRepository;
|
NodeRepository = nodeRepository;
|
||||||
NodeService = nodeService;
|
NodeService = nodeService;
|
||||||
|
PleskServerRepository = pleskServerRepository;
|
||||||
|
WebsiteService = websiteService;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<Node?> GetNode()
|
public async Task<Node?> GetNode()
|
||||||
@@ -32,6 +38,21 @@ public class SmartDeployService
|
|||||||
return data.MaxBy(x => x.Value).Key;
|
return data.MaxBy(x => x.Value).Key;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task<PleskServer?> GetPleskServer()
|
||||||
|
{
|
||||||
|
var result = new List<PleskServer>();
|
||||||
|
|
||||||
|
foreach (var pleskServer in PleskServerRepository.Get().ToArray())
|
||||||
|
{
|
||||||
|
if (await WebsiteService.IsHostUp(pleskServer))
|
||||||
|
{
|
||||||
|
result.Add(pleskServer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result.FirstOrDefault();
|
||||||
|
}
|
||||||
|
|
||||||
private async Task<double> GetUsageScore(Node node)
|
private async Task<double> GetUsageScore(Node node)
|
||||||
{
|
{
|
||||||
var score = 0;
|
var score = 0;
|
||||||
|
|||||||
@@ -27,7 +27,7 @@
|
|||||||
<TL>No node found</TL>
|
<TL>No node found</TL>
|
||||||
</h4>
|
</h4>
|
||||||
<p class="card-text">
|
<p class="card-text">
|
||||||
<TL>No node found to deploy to found</TL>
|
<TL>No node found to deploy to</TL>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -36,8 +36,8 @@
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
<div class="d-flex flex-column flex-lg-row">
|
<div class="d-flex flex-column flex-lg-row">
|
||||||
<div class="w-100 flex-lg-row-auto w-lg-300px mb-7 me-7 me-lg-10" data-select2-id="select2-data-131-dr2d">
|
<div class="w-100 flex-lg-row-auto w-lg-300px mb-7 me-7 me-lg-10">
|
||||||
<div class="card card-flush py-4" data-select2-id="select2-data-130-ru5y">
|
<div class="card card-flush py-4">
|
||||||
<div class="card-header">
|
<div class="card-header">
|
||||||
<div class="card-title">
|
<div class="card-title">
|
||||||
<h2>
|
<h2>
|
||||||
@@ -48,7 +48,7 @@
|
|||||||
<div class="card-body pt-0">
|
<div class="card-body pt-0">
|
||||||
<div class="d-flex flex-column gap-10">
|
<div class="d-flex flex-column gap-10">
|
||||||
<div class="fv-row">
|
<div class="fv-row">
|
||||||
<label class="form-label">Node</label>
|
<label class="form-label"><TL>Node</TL></label>
|
||||||
<div class="fw-bold fs-3">@(DeployNode.Name)</div>
|
<div class="fw-bold fs-3">@(DeployNode.Name)</div>
|
||||||
</div>
|
</div>
|
||||||
@if (Model.Image != null)
|
@if (Model.Image != null)
|
||||||
@@ -159,11 +159,9 @@
|
|||||||
Subscription = await SubscriptionService.GetCurrent();
|
Subscription = await SubscriptionService.GetCurrent();
|
||||||
|
|
||||||
await lazyLoader.SetText(SmartTranslateService.Translate("Searching for deploy node"));
|
await lazyLoader.SetText(SmartTranslateService.Translate("Searching for deploy node"));
|
||||||
|
|
||||||
DeployNode = await SmartDeployService.GetNode();
|
DeployNode = await SmartDeployService.GetNode();
|
||||||
|
|
||||||
await lazyLoader.SetText(SmartTranslateService.Translate("Searching for available images"));
|
await lazyLoader.SetText(SmartTranslateService.Translate("Searching for available images"));
|
||||||
|
|
||||||
var images = ImageRepository.Get().ToArray();
|
var images = ImageRepository.Get().ToArray();
|
||||||
|
|
||||||
foreach (var image in images)
|
foreach (var image in images)
|
||||||
@@ -179,7 +177,7 @@
|
|||||||
.Where(x => x.Owner.Id == User.Id)
|
.Where(x => x.Owner.Id == User.Id)
|
||||||
.Count(x => x.Image.Id == image.Id);
|
.Count(x => x.Image.Id == image.Id);
|
||||||
|
|
||||||
if(serversCount <= limit.Amount) //TODO: FIX COUNTING
|
if(serversCount < limit.Amount)
|
||||||
Images.Add(image, limit);
|
Images.Add(image, limit);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
138
Moonlight/Shared/Views/Websites/Create.razor
Normal file
138
Moonlight/Shared/Views/Websites/Create.razor
Normal file
@@ -0,0 +1,138 @@
|
|||||||
|
@page "/websites/create"
|
||||||
|
@using Moonlight.App.Services
|
||||||
|
@using Moonlight.App.Database.Entities
|
||||||
|
@using Moonlight.App.Models.Forms
|
||||||
|
@using Moonlight.App.Repositories
|
||||||
|
|
||||||
|
@inject SubscriptionService SubscriptionService
|
||||||
|
@inject WebsiteService WebsiteService
|
||||||
|
@inject WebsiteRepository WebsiteRepository
|
||||||
|
@inject SmartDeployService SmartDeployService
|
||||||
|
@inject SmartTranslateService SmartTranslateService
|
||||||
|
@inject NavigationManager NavigationManager
|
||||||
|
|
||||||
|
<LazyLoader Load="Load">
|
||||||
|
@if (PleskServer == null)
|
||||||
|
{
|
||||||
|
<div class="d-flex justify-content-center flex-center">
|
||||||
|
<div class="card">
|
||||||
|
<img src="/assets/media/svg/nodata.svg" class="card-img-top w-25 mx-auto pt-5" alt="Not found image"/>
|
||||||
|
<div class="card-body text-center">
|
||||||
|
<h4 class="card-title">
|
||||||
|
<TL>No plesk server found</TL>
|
||||||
|
</h4>
|
||||||
|
<p class="card-text">
|
||||||
|
<TL>No plesk server found to deploy to</TL>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
<div class="d-flex flex-column flex-lg-row">
|
||||||
|
<div class="w-100 flex-lg-row-auto w-lg-300px mb-7 me-7 me-lg-10">
|
||||||
|
<div class="card card-flush py-4">
|
||||||
|
<div class="card-header">
|
||||||
|
<div class="card-title">
|
||||||
|
<h2>
|
||||||
|
<TL>Website details</TL>
|
||||||
|
</h2>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="card-body pt-0">
|
||||||
|
<div class="d-flex flex-column gap-10">
|
||||||
|
<div class="fv-row">
|
||||||
|
<label class="form-label">
|
||||||
|
<TL>Plesk server</TL>
|
||||||
|
</label>
|
||||||
|
<div class="fw-bold fs-3">@(PleskServer.Name)</div>
|
||||||
|
</div>
|
||||||
|
@if (AllowOrder)
|
||||||
|
{
|
||||||
|
<div class="fv-row">
|
||||||
|
<label class="form-label">
|
||||||
|
<TL>Domain</TL>
|
||||||
|
</label>
|
||||||
|
<div class="fw-bold fs-3">@(Model.BaseDomain)</div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="d-flex flex-column flex-lg-row-fluid gap-7 gap-lg-10">
|
||||||
|
<div class="card card-flush py-4">
|
||||||
|
<div class="card-header">
|
||||||
|
<div class="card-title">
|
||||||
|
<h2>
|
||||||
|
<TL>Configure your website</TL>
|
||||||
|
</h2>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="card-body pt-0">
|
||||||
|
<SmartForm Model="Model" OnValidSubmit="OnValidSubmit">
|
||||||
|
@if (AllowOrder)
|
||||||
|
{
|
||||||
|
<label class="form-label">
|
||||||
|
<TL>Domain</TL>
|
||||||
|
</label>
|
||||||
|
<div class="input-group mb-5">
|
||||||
|
<InputText @bind-Value="Model.BaseDomain" class="form-control"></InputText>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<button type="submit" class="mt-5 float-end btn btn-primary">
|
||||||
|
<TL>Create</TL>
|
||||||
|
</button>
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
<div class="alert alert-warning d-flex align-items-center p-5 mb-10">
|
||||||
|
<span>
|
||||||
|
<TL>You reached the maximum amount of websites in your subscription</TL>: @(Subscription == null ? SmartTranslateService.Translate("Default") : Subscription.Name)
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
</SmartForm>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
</LazyLoader>
|
||||||
|
|
||||||
|
@code
|
||||||
|
{
|
||||||
|
[CascadingParameter]
|
||||||
|
public User User { get; set; }
|
||||||
|
|
||||||
|
private Subscription? Subscription;
|
||||||
|
private PleskServer? PleskServer;
|
||||||
|
private bool AllowOrder = false;
|
||||||
|
|
||||||
|
private WebsiteOrderDataModel Model = new();
|
||||||
|
|
||||||
|
private async Task Load(LazyLoader lazyLoader)
|
||||||
|
{
|
||||||
|
// Reset state
|
||||||
|
Model = new();
|
||||||
|
|
||||||
|
await lazyLoader.SetText(SmartTranslateService.Translate("Loading your subscription"));
|
||||||
|
Subscription = await SubscriptionService.GetCurrent();
|
||||||
|
|
||||||
|
await lazyLoader.SetText(SmartTranslateService.Translate("Searching for deploy plesk server"));
|
||||||
|
PleskServer = await SmartDeployService.GetPleskServer();
|
||||||
|
|
||||||
|
AllowOrder = WebsiteRepository.Get().Count() < (await SubscriptionService.GetLimit("websites")).Amount;
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task OnValidSubmit()
|
||||||
|
{
|
||||||
|
if (WebsiteRepository.Get().Count() < (await SubscriptionService.GetLimit("websites")).Amount)
|
||||||
|
{
|
||||||
|
var website = await WebsiteService.Create(Model.BaseDomain, User, PleskServer);
|
||||||
|
|
||||||
|
NavigationManager.NavigateTo($"/website/{website.Id}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1 +0,0 @@
|
|||||||
@page "/websites/new"
|
|
||||||
@@ -531,3 +531,7 @@ Month;Month
|
|||||||
Year;Year
|
Year;Year
|
||||||
All time;All time
|
All time;All time
|
||||||
This function is not implemented;This function is not implemented
|
This function is not implemented;This function is not implemented
|
||||||
|
Searching for deploy plesk server;Searching for deploy plesk server
|
||||||
|
Website details;Website details
|
||||||
|
Configure your website;Configure your website
|
||||||
|
You reached the maximum amount of websites in your subscription;You reached the maximum amount of websites in your subscription
|
||||||
|
|||||||
Reference in New Issue
Block a user