Merge pull request #55 from Moonlight-Panel/DomainOrder
Implemented domain order. Fixed some bugs
This commit is contained in:
15
Moonlight/App/Models/Forms/DomainOrderDataModel.cs
Normal file
15
Moonlight/App/Models/Forms/DomainOrderDataModel.cs
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
using Moonlight.App.Database.Entities;
|
||||||
|
|
||||||
|
namespace Moonlight.App.Models.Forms;
|
||||||
|
|
||||||
|
public class DomainOrderDataModel
|
||||||
|
{
|
||||||
|
[Required(ErrorMessage = "You need to specify a name")]
|
||||||
|
[MaxLength(32, ErrorMessage = "The max lenght for the name is 32 characters")]
|
||||||
|
[RegularExpression(@"^[a-z]+$", ErrorMessage = "The name should only consist of lower case characters")]
|
||||||
|
public string Name { get; set; } = "";
|
||||||
|
|
||||||
|
[Required(ErrorMessage = "You need to specify a shared domain")]
|
||||||
|
public SharedDomain SharedDomain { get; set; }
|
||||||
|
}
|
||||||
@@ -48,6 +48,28 @@ public class DomainService
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Task<Domain> Create(string domain, SharedDomain sharedDomain, User user)
|
||||||
|
{
|
||||||
|
if (DomainRepository.Get().Where(x => x.SharedDomain.Id == sharedDomain.Id).Any(x => x.Name == domain))
|
||||||
|
throw new DisplayException("A domain with this name does already exist for this shared domain");
|
||||||
|
|
||||||
|
var res = DomainRepository.Add(new()
|
||||||
|
{
|
||||||
|
Name = domain,
|
||||||
|
SharedDomain = sharedDomain,
|
||||||
|
Owner = user
|
||||||
|
});
|
||||||
|
|
||||||
|
return Task.FromResult(res);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task Delete(Domain domain)
|
||||||
|
{
|
||||||
|
DomainRepository.Delete(domain);
|
||||||
|
|
||||||
|
return Task.CompletedTask;
|
||||||
|
}
|
||||||
|
|
||||||
public async Task<Zone[]>
|
public async Task<Zone[]>
|
||||||
GetAvailableDomains() // This method returns all available domains which are not added as a shared domain
|
GetAvailableDomains() // This method returns all available domains which are not added as a shared domain
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -6,10 +6,11 @@
|
|||||||
@using Moonlight.App.Services
|
@using Moonlight.App.Services
|
||||||
|
|
||||||
@inject DomainRepository DomainRepository
|
@inject DomainRepository DomainRepository
|
||||||
|
@inject DomainService DomainService
|
||||||
@inject SmartTranslateService SmartTranslateService
|
@inject SmartTranslateService SmartTranslateService
|
||||||
|
|
||||||
<OnlyAdmin>
|
<OnlyAdmin>
|
||||||
<LazyLoader Load="Load">
|
<LazyLoader @ref="LazyLoader" Load="Load">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="card">
|
<div class="card">
|
||||||
<div class="card-header border-0 pt-5">
|
<div class="card-header border-0 pt-5">
|
||||||
@@ -47,11 +48,9 @@
|
|||||||
</Column>
|
</Column>
|
||||||
<Column TableItem="Domain" Title="" Field="@(x => x.Id)" Sortable="false" Filterable="false" Width="10%">
|
<Column TableItem="Domain" Title="" Field="@(x => x.Id)" Sortable="false" Filterable="false" Width="10%">
|
||||||
<Template>
|
<Template>
|
||||||
<WButton Text="@(SmartTranslateService.Translate("Delete"))"
|
<DeleteButton Confirm="true"
|
||||||
WorkingText="@(SmartTranslateService.Translate("Deleting"))"
|
OnClick="() => Delete(context)">
|
||||||
CssClasses="btn-sm btn-danger"
|
</DeleteButton>
|
||||||
OnClick="() => Delete(context)">
|
|
||||||
</WButton>
|
|
||||||
</Template>
|
</Template>
|
||||||
</Column>
|
</Column>
|
||||||
</Table>
|
</Table>
|
||||||
@@ -65,6 +64,7 @@
|
|||||||
@code
|
@code
|
||||||
{
|
{
|
||||||
private Domain[] Domains;
|
private Domain[] Domains;
|
||||||
|
private LazyLoader LazyLoader;
|
||||||
|
|
||||||
private Task Load(LazyLoader arg)
|
private Task Load(LazyLoader arg)
|
||||||
{
|
{
|
||||||
@@ -79,5 +79,7 @@
|
|||||||
|
|
||||||
private async Task Delete(Domain context)
|
private async Task Delete(Domain context)
|
||||||
{
|
{
|
||||||
|
await DomainService.Delete(context);
|
||||||
|
await LazyLoader.Reload();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -4,13 +4,12 @@
|
|||||||
@using Moonlight.App.Models.Forms
|
@using Moonlight.App.Models.Forms
|
||||||
@using Moonlight.App.Repositories
|
@using Moonlight.App.Repositories
|
||||||
@using Moonlight.App.Repositories.Domains
|
@using Moonlight.App.Repositories.Domains
|
||||||
@using Mappy.Net
|
|
||||||
|
|
||||||
@inject SmartTranslateService SmartTranslateService
|
@inject SmartTranslateService SmartTranslateService
|
||||||
@inject SharedDomainRepository SharedDomainRepository
|
@inject SharedDomainRepository SharedDomainRepository
|
||||||
@inject DomainRepository DomainRepository
|
|
||||||
@inject UserRepository UserRepository
|
@inject UserRepository UserRepository
|
||||||
@inject NavigationManager NavigationManager
|
@inject NavigationManager NavigationManager
|
||||||
|
@inject DomainService DomainService
|
||||||
|
|
||||||
<OnlyAdmin>
|
<OnlyAdmin>
|
||||||
<div class="row mb-5">
|
<div class="row mb-5">
|
||||||
@@ -66,14 +65,10 @@
|
|||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Task Add()
|
private async Task Add()
|
||||||
{
|
{
|
||||||
var domain = Mapper.Map<Domain>(Model);
|
await DomainService.Create(Model.Name, Model.SharedDomain, Model.Owner);
|
||||||
|
|
||||||
DomainRepository.Add(domain);
|
|
||||||
|
|
||||||
NavigationManager.NavigateTo("/admin/domains");
|
NavigationManager.NavigateTo("/admin/domains");
|
||||||
|
|
||||||
return Task.CompletedTask;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
156
Moonlight/Shared/Views/Domains/Create.razor
Normal file
156
Moonlight/Shared/Views/Domains/Create.razor
Normal file
@@ -0,0 +1,156 @@
|
|||||||
|
@page "/domains/create"
|
||||||
|
@using Moonlight.App.Services
|
||||||
|
@using Moonlight.App.Database.Entities
|
||||||
|
@using Moonlight.App.Models.Forms
|
||||||
|
@using Moonlight.App.Repositories.Domains
|
||||||
|
@using Microsoft.EntityFrameworkCore
|
||||||
|
|
||||||
|
@inject SubscriptionService SubscriptionService
|
||||||
|
@inject DomainService DomainService
|
||||||
|
@inject DomainRepository DomainRepository
|
||||||
|
@inject SharedDomainRepository SharedDomainRepository
|
||||||
|
@inject NavigationManager NavigationManager
|
||||||
|
@inject SmartTranslateService SmartTranslateService
|
||||||
|
|
||||||
|
<LazyLoader Load="Load">
|
||||||
|
@if (!SharedDomains.Any())
|
||||||
|
{
|
||||||
|
<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 shared domain found</TL>
|
||||||
|
</h4>
|
||||||
|
<p class="card-text">
|
||||||
|
<TL>No shared domain found</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>Domain details</TL>
|
||||||
|
</h2>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="card-body pt-0">
|
||||||
|
<div class="d-flex flex-column gap-10">
|
||||||
|
@if (AllowOrder)
|
||||||
|
{
|
||||||
|
<div class="fv-row">
|
||||||
|
<label class="form-label">
|
||||||
|
<TL>Name</TL>
|
||||||
|
</label>
|
||||||
|
<div class="fw-bold fs-3">@(Model.Name)</div>
|
||||||
|
</div>
|
||||||
|
<div class="fv-row">
|
||||||
|
<label class="form-label">
|
||||||
|
<TL>Shared domain</TL>
|
||||||
|
</label>
|
||||||
|
<div class="fw-bold fs-3">@(Model.SharedDomain == null ? "" : Model.SharedDomain.Name)</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 domain</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.Name" class="form-control"></InputText>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="mb-5">
|
||||||
|
<label class="form-label">
|
||||||
|
<TL>Shared domain</TL>
|
||||||
|
</label>
|
||||||
|
<SmartSelect @bind-Value="Model.SharedDomain"
|
||||||
|
Items="SharedDomains"
|
||||||
|
DisplayField="@(x => x.Name)">
|
||||||
|
</SmartSelect>
|
||||||
|
</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 domains 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 SharedDomain[] SharedDomains;
|
||||||
|
|
||||||
|
private Subscription? Subscription;
|
||||||
|
|
||||||
|
private bool AllowOrder = false;
|
||||||
|
|
||||||
|
private DomainOrderDataModel Model = new();
|
||||||
|
|
||||||
|
private async Task Load(LazyLoader lazyLoader)
|
||||||
|
{
|
||||||
|
Model = new();
|
||||||
|
|
||||||
|
await lazyLoader.SetText(SmartTranslateService.Translate("Loading your subscription"));
|
||||||
|
Subscription = await SubscriptionService.GetCurrent();
|
||||||
|
|
||||||
|
AllowOrder = DomainRepository
|
||||||
|
.Get()
|
||||||
|
.Include(x => x.Owner)
|
||||||
|
.Count(x => x.Owner.Id == User.Id) < (await SubscriptionService.GetLimit("domains")).Amount;
|
||||||
|
|
||||||
|
await lazyLoader.SetText("Loading shared domains");
|
||||||
|
SharedDomains = SharedDomainRepository.Get().ToArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task OnValidSubmit()
|
||||||
|
{
|
||||||
|
if (DomainRepository
|
||||||
|
.Get()
|
||||||
|
.Include(x => x.Owner)
|
||||||
|
.Count(x => x.Owner.Id == User.Id) < (await SubscriptionService.GetLimit("domains")).Amount)
|
||||||
|
{
|
||||||
|
var domain = await DomainService.Create(Model.Name, Model.SharedDomain, User);
|
||||||
|
|
||||||
|
NavigationManager.NavigateTo($"/domain/{domain.Id}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -3,6 +3,7 @@
|
|||||||
@using Moonlight.App.Database.Entities
|
@using Moonlight.App.Database.Entities
|
||||||
@using Moonlight.App.Models.Forms
|
@using Moonlight.App.Models.Forms
|
||||||
@using Moonlight.App.Repositories
|
@using Moonlight.App.Repositories
|
||||||
|
@using Microsoft.EntityFrameworkCore
|
||||||
|
|
||||||
@inject SubscriptionService SubscriptionService
|
@inject SubscriptionService SubscriptionService
|
||||||
@inject WebsiteService WebsiteService
|
@inject WebsiteService WebsiteService
|
||||||
@@ -123,7 +124,10 @@
|
|||||||
await lazyLoader.SetText(SmartTranslateService.Translate("Searching for deploy plesk server"));
|
await lazyLoader.SetText(SmartTranslateService.Translate("Searching for deploy plesk server"));
|
||||||
PleskServer = await SmartDeployService.GetPleskServer();
|
PleskServer = await SmartDeployService.GetPleskServer();
|
||||||
|
|
||||||
AllowOrder = WebsiteRepository.Get().Count() < (await SubscriptionService.GetLimit("websites")).Amount;
|
AllowOrder = WebsiteRepository
|
||||||
|
.Get()
|
||||||
|
.Include(x => x.Owner)
|
||||||
|
.Count(x => x.Owner.Id == User.Id) < (await SubscriptionService.GetLimit("websites")).Amount;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task OnValidSubmit()
|
private async Task OnValidSubmit()
|
||||||
|
|||||||
@@ -531,3 +531,8 @@ 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
|
||||||
|
Domain details;Domain details
|
||||||
|
Configure your domain;Configure your domain
|
||||||
|
You reached the maximum amount of domains in your subscription;You reached the maximum amount of domains in your subscription
|
||||||
|
You need to specify a shared domain;You need to specify a shared domain
|
||||||
|
A domain with this name does already exist for this shared domain;A domain with this name does already exist for this shared domain
|
||||||
|
|||||||
@@ -19,3 +19,67 @@ Forgot password?;Forgot password?
|
|||||||
Sign-in;Sign-in
|
Sign-in;Sign-in
|
||||||
Not registered yet?;Not registered yet?
|
Not registered yet?;Not registered yet?
|
||||||
Sign up;Sign up
|
Sign up;Sign up
|
||||||
|
Profile;Profile
|
||||||
|
Logout;Logout
|
||||||
|
Dashboard;Dashboard
|
||||||
|
Servers;Servers
|
||||||
|
Websites;Websites
|
||||||
|
Domains;Domains
|
||||||
|
Changelog;Changelog
|
||||||
|
Admin;Admin
|
||||||
|
System;System
|
||||||
|
Overview;Overview
|
||||||
|
Manager;Manager
|
||||||
|
Cleanup;Cleanup
|
||||||
|
Nodes;Nodes
|
||||||
|
Images;Images
|
||||||
|
Users;Users
|
||||||
|
Shared domains;Shared domains
|
||||||
|
Support;Support
|
||||||
|
Subscriptions;Subscriptions
|
||||||
|
Statistics;Statistics
|
||||||
|
Create something new;Create something new
|
||||||
|
Create a gameserver;Create a gameserver
|
||||||
|
A new gameserver in just a few minutes;A new gameserver in just a few minutes
|
||||||
|
Create a website;Create a website
|
||||||
|
Make your own websites with a webspace;Make your own websites with a webspace
|
||||||
|
Create a domain;Create a domain
|
||||||
|
Make your servvices accessible throught your own domain;Make your servvices accessible throught your own domain
|
||||||
|
Manage your services;Manage your services
|
||||||
|
Manage your gameservers;Manage your gameservers
|
||||||
|
Adjust your gameservers;Adjust your gameservers
|
||||||
|
Manage your websites;Manage your websites
|
||||||
|
Modify the content of your websites;Modify the content of your websites
|
||||||
|
Manage your domains;Manage your domains
|
||||||
|
Add, edit and delete dns records;Add, edit and delete dns records
|
||||||
|
New server;New server
|
||||||
|
Id;Id
|
||||||
|
Name;Name
|
||||||
|
Cores;Cores
|
||||||
|
Memory;Memory
|
||||||
|
Disk;Disk
|
||||||
|
Owner;Owner
|
||||||
|
Manage;Manage
|
||||||
|
Node offline;Node offline
|
||||||
|
The node the server is running on is currently offline;The node the server is running on is currently offline
|
||||||
|
Sessions;Sessions
|
||||||
|
New user;New user
|
||||||
|
First name;First name
|
||||||
|
Last name;Last name
|
||||||
|
Created at;Created at
|
||||||
|
Refresh;Refresh
|
||||||
|
Send a message to all users;Send a message to all users
|
||||||
|
IP;IP
|
||||||
|
URL;URL
|
||||||
|
Device;Device
|
||||||
|
Time;Time
|
||||||
|
Actions;Actions
|
||||||
|
Change url;Change url
|
||||||
|
Message;Message
|
||||||
|
Enter url;Enter url
|
||||||
|
Send;Send
|
||||||
|
Sending;Sending
|
||||||
|
Welcome to the support chat. Ask your question here and we will help you;Welcome to the support chat. Ask your question here and we will help you
|
||||||
|
less than a minute ago;less than a minute ago
|
||||||
|
The support team has been notified. Please be patient;The support team has been notified. Please be patient
|
||||||
|
is typing;is typing
|
||||||
|
|||||||
Reference in New Issue
Block a user