Переглянути джерело

Merge pull request #55 from Moonlight-Panel/DomainOrder

Implemented domain order. Fixed some bugs
Marcel Baumgartner 2 роки тому
батько
коміт
6e4a269c35

+ 15 - 0
Moonlight/App/Models/Forms/DomainOrderDataModel.cs

@@ -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; }
+}

+ 22 - 0
Moonlight/App/Services/DomainService.cs

@@ -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[]>
         GetAvailableDomains() // This method returns all available domains which are not added as a shared domain
     {

+ 8 - 6
Moonlight/Shared/Views/Admin/Domains/Index.razor

@@ -6,10 +6,11 @@
 @using Moonlight.App.Services
 
 @inject DomainRepository DomainRepository
+@inject DomainService DomainService
 @inject SmartTranslateService SmartTranslateService
 
 <OnlyAdmin>
-    <LazyLoader Load="Load">
+    <LazyLoader @ref="LazyLoader" Load="Load">
         <div class="row">
             <div class="card">
                 <div class="card-header border-0 pt-5">
@@ -47,11 +48,9 @@
                             </Column>
                             <Column TableItem="Domain" Title="" Field="@(x => x.Id)" Sortable="false" Filterable="false" Width="10%">
                                 <Template>
-                                    <WButton Text="@(SmartTranslateService.Translate("Delete"))"
-                                             WorkingText="@(SmartTranslateService.Translate("Deleting"))"
-                                             CssClasses="btn-sm btn-danger"
-                                             OnClick="() => Delete(context)">
-                                    </WButton>
+                                    <DeleteButton Confirm="true"
+                                                  OnClick="() => Delete(context)">
+                                    </DeleteButton>
                                 </Template>
                             </Column>
                         </Table>
@@ -65,6 +64,7 @@
 @code
 {
     private Domain[] Domains;
+    private LazyLoader LazyLoader;
 
     private Task Load(LazyLoader arg)
     {
@@ -79,5 +79,7 @@
 
     private async Task Delete(Domain context)
     {
+        await DomainService.Delete(context);
+        await LazyLoader.Reload();
     }
 }

+ 3 - 8
Moonlight/Shared/Views/Admin/Domains/New.razor

@@ -4,13 +4,12 @@
 @using Moonlight.App.Models.Forms
 @using Moonlight.App.Repositories
 @using Moonlight.App.Repositories.Domains
-@using Mappy.Net
 
 @inject SmartTranslateService SmartTranslateService
 @inject SharedDomainRepository SharedDomainRepository
-@inject DomainRepository DomainRepository
 @inject UserRepository UserRepository
 @inject NavigationManager NavigationManager
+@inject DomainService DomainService
 
 <OnlyAdmin>
     <div class="row mb-5">
@@ -66,14 +65,10 @@
         return Task.CompletedTask;
     }
 
-    private Task Add()
+    private async Task Add()
     {
-        var domain = Mapper.Map<Domain>(Model);
-
-        DomainRepository.Add(domain);
+        await DomainService.Create(Model.Name, Model.SharedDomain, Model.Owner);
 
         NavigationManager.NavigateTo("/admin/domains");
-
-        return Task.CompletedTask;
     }
 }

+ 156 - 0
Moonlight/Shared/Views/Domains/Create.razor

@@ -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}");
+        }
+    }
+}

+ 0 - 0
Moonlight/Shared/Views/Domains.razor → Moonlight/Shared/Views/Domains/Index.razor


+ 5 - 1
Moonlight/Shared/Views/Websites/Create.razor

@@ -3,6 +3,7 @@
 @using Moonlight.App.Database.Entities
 @using Moonlight.App.Models.Forms
 @using Moonlight.App.Repositories
+@using Microsoft.EntityFrameworkCore
 
 @inject SubscriptionService SubscriptionService
 @inject WebsiteService WebsiteService
@@ -123,7 +124,10 @@
         await lazyLoader.SetText(SmartTranslateService.Translate("Searching for deploy plesk server"));
         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()

+ 5 - 0
Moonlight/resources/lang/de_de.lang

@@ -531,3 +531,8 @@ Month;Month
 Year;Year
 All time;All time
 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

+ 64 - 0
Moonlight/resources/lang/en_us.lang

@@ -19,3 +19,67 @@ Forgot password?;Forgot password?
 Sign-in;Sign-in
 Not registered yet?;Not registered yet?
 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