Implemented databases. Fixed nav bars. Some fixes
This commit is contained in:
18
Moonlight/App/ApiClients/CloudPanel/Requests/AddDatabase.cs
Normal file
18
Moonlight/App/ApiClients/CloudPanel/Requests/AddDatabase.cs
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
|
namespace Moonlight.App.ApiClients.CloudPanel.Requests;
|
||||||
|
|
||||||
|
public class AddDatabase
|
||||||
|
{
|
||||||
|
[JsonProperty("domainName")]
|
||||||
|
public string DomainName { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("databaseName")]
|
||||||
|
public string DatabaseName { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("databaseUserName")]
|
||||||
|
public string DatabaseUserName { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("databaseUserPassword")]
|
||||||
|
public string DatabaseUserPassword { get; set; }
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
|
namespace Moonlight.App.ApiClients.CloudPanel.Requests;
|
||||||
|
|
||||||
|
public class InstallLetsEncrypt
|
||||||
|
{
|
||||||
|
[JsonProperty("domainName")]
|
||||||
|
public string DomainName { get; set; }
|
||||||
|
}
|
||||||
@@ -7,7 +7,7 @@ public class DomainOrderDataModel
|
|||||||
{
|
{
|
||||||
[Required(ErrorMessage = "You need to specify a name")]
|
[Required(ErrorMessage = "You need to specify a name")]
|
||||||
[MaxLength(32, ErrorMessage = "The max lenght for the name is 32 characters")]
|
[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")]
|
[RegularExpression(@"^[a-z0-9]+$", ErrorMessage = "The name should only consist of lower case characters or numbers")]
|
||||||
public string Name { get; set; } = "";
|
public string Name { get; set; } = "";
|
||||||
|
|
||||||
[Required(ErrorMessage = "You need to specify a shared domain")]
|
[Required(ErrorMessage = "You need to specify a shared domain")]
|
||||||
|
|||||||
@@ -6,18 +6,20 @@ namespace Moonlight.App.Services;
|
|||||||
public class SmartDeployService
|
public class SmartDeployService
|
||||||
{
|
{
|
||||||
private readonly NodeRepository NodeRepository;
|
private readonly NodeRepository NodeRepository;
|
||||||
private readonly PleskServerRepository PleskServerRepository;
|
private readonly Repository<CloudPanel> CloudPanelRepository;
|
||||||
private readonly WebSpaceService WebSpaceService;
|
private readonly WebSpaceService WebSpaceService;
|
||||||
private readonly NodeService NodeService;
|
private readonly NodeService NodeService;
|
||||||
|
|
||||||
public SmartDeployService(
|
public SmartDeployService(
|
||||||
NodeRepository nodeRepository,
|
NodeRepository nodeRepository,
|
||||||
NodeService nodeService, PleskServerRepository pleskServerRepository, WebSpaceService webSpaceService)
|
NodeService nodeService,
|
||||||
|
WebSpaceService webSpaceService,
|
||||||
|
Repository<CloudPanel> cloudPanelRepository)
|
||||||
{
|
{
|
||||||
NodeRepository = nodeRepository;
|
NodeRepository = nodeRepository;
|
||||||
NodeService = nodeService;
|
NodeService = nodeService;
|
||||||
PleskServerRepository = pleskServerRepository;
|
|
||||||
WebSpaceService = webSpaceService;
|
WebSpaceService = webSpaceService;
|
||||||
|
CloudPanelRepository = cloudPanelRepository;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<Node?> GetNode()
|
public async Task<Node?> GetNode()
|
||||||
@@ -38,13 +40,14 @@ public class SmartDeployService
|
|||||||
return data.MaxBy(x => x.Value).Key;
|
return data.MaxBy(x => x.Value).Key;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<PleskServer?> GetPleskServer()
|
public async Task<CloudPanel?> GetCloudPanel()
|
||||||
{
|
{
|
||||||
var result = new List<PleskServer>();
|
var result = new List<CloudPanel>();
|
||||||
|
|
||||||
foreach (var pleskServer in PleskServerRepository.Get().ToArray())
|
foreach (var cloudPanel in CloudPanelRepository.Get().ToArray())
|
||||||
{
|
{
|
||||||
result.Add(pleskServer);
|
if (await WebSpaceService.IsHostUp(cloudPanel))
|
||||||
|
result.Add(cloudPanel);
|
||||||
}
|
}
|
||||||
|
|
||||||
return result.FirstOrDefault();
|
return result.FirstOrDefault();
|
||||||
|
|||||||
@@ -17,13 +17,16 @@ public class WebSpaceService
|
|||||||
{
|
{
|
||||||
private readonly Repository<CloudPanel> CloudPanelRepository;
|
private readonly Repository<CloudPanel> CloudPanelRepository;
|
||||||
private readonly Repository<WebSpace> WebSpaceRepository;
|
private readonly Repository<WebSpace> WebSpaceRepository;
|
||||||
|
private readonly Repository<MySqlDatabase> DatabaseRepository;
|
||||||
|
|
||||||
private readonly CloudPanelApiHelper CloudPanelApiHelper;
|
private readonly CloudPanelApiHelper CloudPanelApiHelper;
|
||||||
|
|
||||||
public WebSpaceService(Repository<CloudPanel> cloudPanelRepository, Repository<WebSpace> webSpaceRepository, CloudPanelApiHelper cloudPanelApiHelper)
|
public WebSpaceService(Repository<CloudPanel> cloudPanelRepository, Repository<WebSpace> webSpaceRepository, CloudPanelApiHelper cloudPanelApiHelper, Repository<MySqlDatabase> databaseRepository)
|
||||||
{
|
{
|
||||||
CloudPanelRepository = cloudPanelRepository;
|
CloudPanelRepository = cloudPanelRepository;
|
||||||
WebSpaceRepository = webSpaceRepository;
|
WebSpaceRepository = webSpaceRepository;
|
||||||
CloudPanelApiHelper = cloudPanelApiHelper;
|
CloudPanelApiHelper = cloudPanelApiHelper;
|
||||||
|
DatabaseRepository = databaseRepository;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<WebSpace> Create(string domain, User owner, CloudPanel? ps = null)
|
public async Task<WebSpace> Create(string domain, User owner, CloudPanel? ps = null)
|
||||||
@@ -83,14 +86,16 @@ public class WebSpaceService
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
//var res = await PleskApiHelper.Get<ServerStatus>(pleskServer, "server");
|
await CloudPanelApiHelper.Post(cloudPanel, "", null);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
//if (res != null)
|
|
||||||
// return true;
|
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (CloudPanelException e)
|
||||||
|
{
|
||||||
|
if (e.StatusCode == 404)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
{
|
{
|
||||||
// ignored
|
// ignored
|
||||||
}
|
}
|
||||||
@@ -105,40 +110,60 @@ public class WebSpaceService
|
|||||||
return await IsHostUp(webSpace.CloudPanel);
|
return await IsHostUp(webSpace.CloudPanel);
|
||||||
}
|
}
|
||||||
|
|
||||||
#region SSL
|
public async Task IssueSslCertificate(WebSpace w)
|
||||||
public async Task<string[]> GetSslCertificates(WebSpace w)
|
|
||||||
{
|
{
|
||||||
var certs = new List<string>();
|
var webspace = EnsureData(w);
|
||||||
return certs.ToArray();
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task CreateSslCertificate(WebSpace w)
|
await CloudPanelApiHelper.Post(webspace.CloudPanel, "letsencrypt/install/certificate", new InstallLetsEncrypt()
|
||||||
{
|
{
|
||||||
|
DomainName = webspace.Domain
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task DeleteSslCertificate(WebSpace w, string name)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region Databases
|
#region Databases
|
||||||
|
|
||||||
public async Task<Models.Plesk.Resources.Database[]> GetDatabases(WebSpace w)
|
public Task<MySqlDatabase[]> GetDatabases(WebSpace w)
|
||||||
{
|
{
|
||||||
return Array.Empty<Models.Plesk.Resources.Database>();
|
return Task.FromResult(WebSpaceRepository
|
||||||
|
.Get()
|
||||||
|
.Include(x => x.Databases)
|
||||||
|
.First(x => x.Id == w.Id)
|
||||||
|
.Databases.ToArray());
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task CreateDatabase(WebSpace w, string name, string password)
|
public async Task CreateDatabase(WebSpace w, string name, string password)
|
||||||
{
|
{
|
||||||
|
if (DatabaseRepository.Get().Any(x => x.UserName == name))
|
||||||
|
throw new DisplayException("A database with this name does already exist");
|
||||||
|
|
||||||
|
var webspace = EnsureData(w);
|
||||||
|
|
||||||
|
var database = new MySqlDatabase()
|
||||||
|
{
|
||||||
|
UserName = name,
|
||||||
|
Password = password
|
||||||
|
};
|
||||||
|
|
||||||
|
await CloudPanelApiHelper.Post(webspace.CloudPanel, "db", new AddDatabase()
|
||||||
|
{
|
||||||
|
DomainName = webspace.Domain,
|
||||||
|
DatabaseName = database.UserName,
|
||||||
|
DatabaseUserName = database.UserName,
|
||||||
|
DatabaseUserPassword = database.Password
|
||||||
|
});
|
||||||
|
|
||||||
|
webspace.Databases.Add(database);
|
||||||
|
WebSpaceRepository.Update(webspace);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task DeleteDatabase(WebSpace w, Models.Plesk.Resources.Database database)
|
public async Task DeleteDatabase(WebSpace w, MySqlDatabase database)
|
||||||
{
|
{
|
||||||
|
var webspace = EnsureData(w);
|
||||||
|
|
||||||
|
await CloudPanelApiHelper.Delete(webspace.CloudPanel, $"db/{database.UserName}", null);
|
||||||
|
|
||||||
|
webspace.Databases.Remove(database);
|
||||||
|
WebSpaceRepository.Update(webspace);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|||||||
@@ -9,7 +9,9 @@
|
|||||||
@inject NavigationManager NavigationManager
|
@inject NavigationManager NavigationManager
|
||||||
@inject CookieService CookieService
|
@inject CookieService CookieService
|
||||||
|
|
||||||
<div class="menu menu-column justify-content-center"
|
@if (User != null)
|
||||||
|
{
|
||||||
|
<div class="menu menu-column justify-content-center"
|
||||||
data-kt-menu="true">
|
data-kt-menu="true">
|
||||||
<div class="menu-item">
|
<div class="menu-item">
|
||||||
<div class="dropdown">
|
<div class="dropdown">
|
||||||
@@ -28,14 +30,15 @@
|
|||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<a class="dropdown-item py-2" href="/websites/create">
|
<a class="dropdown-item py-2" href="/webspaces/create">
|
||||||
<TL>Website</TL>
|
<TL>Webspace</TL>
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
}
|
||||||
|
|
||||||
<div class="app-navbar flex-shrink-0">
|
<div class="app-navbar flex-shrink-0">
|
||||||
<div class="app-navbar-item ms-1 ms-lg-3">
|
<div class="app-navbar-item ms-1 ms-lg-3">
|
||||||
|
|||||||
@@ -45,11 +45,11 @@ else
|
|||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="menu-item">
|
<div class="menu-item">
|
||||||
<a class="menu-link" href="/websites">
|
<a class="menu-link" href="/webspaces">
|
||||||
<span class="menu-icon">
|
<span class="menu-icon">
|
||||||
<i class="bx bx-globe"></i>
|
<i class="bx bx-globe"></i>
|
||||||
</span>
|
</span>
|
||||||
<span class="menu-title"><TL>Websites</TL></span>
|
<span class="menu-title"><TL>Webspaces</TL></span>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="menu-item">
|
<div class="menu-item">
|
||||||
@@ -148,11 +148,11 @@ else
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="menu-item">
|
<div class="menu-item">
|
||||||
<a class="menu-link" href="/admin/websites">
|
<a class="menu-link" href="/admin/webspaces">
|
||||||
<span class="menu-icon">
|
<span class="menu-icon">
|
||||||
<i class="bx bx-globe"></i>
|
<i class="bx bx-globe"></i>
|
||||||
</span>
|
</span>
|
||||||
<span class="menu-title"><TL>Websites</TL></span>
|
<span class="menu-title"><TL>Webspaces</TL></span>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="menu-item">
|
<div class="menu-item">
|
||||||
|
|||||||
@@ -1,8 +1,10 @@
|
|||||||
@using Moonlight.App.Database.Entities
|
@using Moonlight.App.Database.Entities
|
||||||
@using Moonlight.App.Services
|
@using Moonlight.App.Services
|
||||||
|
@using Moonlight.App.Services.Interop
|
||||||
|
|
||||||
@inject WebSpaceService WebSpaceService
|
@inject WebSpaceService WebSpaceService
|
||||||
@inject SmartTranslateService SmartTranslateService
|
@inject SmartTranslateService SmartTranslateService
|
||||||
|
@inject AlertService AlertService
|
||||||
|
|
||||||
<div class="row gy-5 g-xl-10">
|
<div class="row gy-5 g-xl-10">
|
||||||
<div class="col-xl-4 mb-xl-10">
|
<div class="col-xl-4 mb-xl-10">
|
||||||
@@ -26,54 +28,10 @@
|
|||||||
<WButton Text="@(SmartTranslateService.Translate("Issue certificate"))"
|
<WButton Text="@(SmartTranslateService.Translate("Issue certificate"))"
|
||||||
WorkingText="@(SmartTranslateService.Translate("Working"))"
|
WorkingText="@(SmartTranslateService.Translate("Working"))"
|
||||||
CssClasses="btn-success"
|
CssClasses="btn-success"
|
||||||
OnClick="CreateCertificate">
|
OnClick="IssueCertificate">
|
||||||
</WButton>
|
</WButton>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="card-body">
|
|
||||||
@if (Certs.Any())
|
|
||||||
{
|
|
||||||
<table class="table align-middle gs-0 gy-3">
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th class="p-0 w-50px"></th>
|
|
||||||
<th class="p-0 min-w-150px"></th>
|
|
||||||
<th class="p-0 min-w-120px"></th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
@foreach (var cert in Certs)
|
|
||||||
{
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
<div class="symbol symbol-50px me-2">
|
|
||||||
<span class="symbol-label">
|
|
||||||
<i class="bx bx-md bx-receipt text-dark"></i>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<span class="text-dark fw-bold fs-6">@(cert)</span>
|
|
||||||
</td>
|
|
||||||
<td class="text-end">
|
|
||||||
<WButton Text="@(SmartTranslateService.Translate("Delete"))"
|
|
||||||
WorkingText="@(SmartTranslateService.Translate("Working"))"
|
|
||||||
CssClasses="btn btn-danger"
|
|
||||||
OnClick="() => DeleteCertificate(cert)">
|
|
||||||
</WButton>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
}
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
<div class="alert alert-warning">
|
|
||||||
<TL>No SSL certificates found</TL>
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</LazyLoader>
|
</LazyLoader>
|
||||||
@@ -87,25 +45,16 @@
|
|||||||
[CascadingParameter]
|
[CascadingParameter]
|
||||||
public WebSpace CurrentWebSpace { get; set; }
|
public WebSpace CurrentWebSpace { get; set; }
|
||||||
|
|
||||||
private string[] Certs;
|
|
||||||
|
|
||||||
private LazyLoader LazyLoader;
|
private LazyLoader LazyLoader;
|
||||||
|
|
||||||
private async Task Load(LazyLoader lazyLoader)
|
private Task Load(LazyLoader lazyLoader)
|
||||||
{
|
{
|
||||||
await lazyLoader.SetText("Loading certificates");
|
return Task.CompletedTask;
|
||||||
Certs = await WebSpaceService.GetSslCertificates(CurrentWebSpace);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task CreateCertificate()
|
private async Task IssueCertificate()
|
||||||
{
|
{
|
||||||
await WebSpaceService.CreateSslCertificate(CurrentWebSpace);
|
await WebSpaceService.IssueSslCertificate(CurrentWebSpace);
|
||||||
await LazyLoader.Reload();
|
await AlertService.Success(SmartTranslateService.Translate("Lets Encrypt certificate successfully issued"));
|
||||||
}
|
|
||||||
|
|
||||||
private async Task DeleteCertificate(string name)
|
|
||||||
{
|
|
||||||
await WebSpaceService.DeleteSslCertificate(CurrentWebSpace, name);
|
|
||||||
await LazyLoader.Reload();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -34,7 +34,7 @@
|
|||||||
<div class="card">
|
<div class="card">
|
||||||
<div class="card-header">
|
<div class="card-header">
|
||||||
<div class="card-title">
|
<div class="card-title">
|
||||||
<span>@(database.Name) - @(database.Type.ToUpper().Replace("MYSQL", "MySQL"))</span>
|
<span>@(database.UserName) - @(database.UserName.ToUpper().Replace("MYSQL", "MySQL"))</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="card-body me-1">
|
<div class="card-body me-1">
|
||||||
@@ -46,7 +46,7 @@
|
|||||||
</label>
|
</label>
|
||||||
</td>
|
</td>
|
||||||
<td class="pb-2">
|
<td class="pb-2">
|
||||||
<input type="text" class="form-control form-control-solid disabled" disabled="disabled" value="@(Host)">
|
<input type="text" class="form-control form-control-solid disabled" disabled="disabled" value="@(CurrentWebSpace.CloudPanel.Host)">
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
@@ -56,7 +56,7 @@
|
|||||||
</label>
|
</label>
|
||||||
</td>
|
</td>
|
||||||
<td class="pb-2">
|
<td class="pb-2">
|
||||||
<input type="text" class="form-control form-control-solid disabled" disabled="disabled" value="@(DatabaseServer.Port)">
|
<input type="text" class="form-control form-control-solid disabled" disabled="disabled" value="3306">
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
@@ -66,7 +66,17 @@
|
|||||||
</label>
|
</label>
|
||||||
</td>
|
</td>
|
||||||
<td class="pb-2">
|
<td class="pb-2">
|
||||||
<input type="text" class="form-control form-control-solid disabled" disabled="disabled" value="@(database.Name)">
|
<input type="text" class="form-control form-control-solid disabled" disabled="disabled" value="@(database.UserName)">
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<label class="fs-6 fw-semibold form-label mt-3">
|
||||||
|
<TL>Password</TL>
|
||||||
|
</label>
|
||||||
|
</td>
|
||||||
|
<td class="pb-2">
|
||||||
|
<input type="text" class="form-control form-control-solid disabled blur-unless-hover" disabled="disabled" value="@(database.Password)">
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
@@ -76,7 +86,7 @@
|
|||||||
</label>
|
</label>
|
||||||
</td>
|
</td>
|
||||||
<td class="pb-2">
|
<td class="pb-2">
|
||||||
<input type="text" class="form-control form-control-solid disabled" disabled="disabled" value="@(database.Name)">
|
<input type="text" class="form-control form-control-solid disabled" disabled="disabled" value="@(database.UserName)">
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
@@ -104,9 +114,7 @@
|
|||||||
public WebSpace CurrentWebSpace { get; set; }
|
public WebSpace CurrentWebSpace { get; set; }
|
||||||
|
|
||||||
private LazyLoader LazyLoader;
|
private LazyLoader LazyLoader;
|
||||||
private Database[] Databases;
|
private MySqlDatabase[] Databases;
|
||||||
private DatabaseServer DatabaseServer;
|
|
||||||
private string Host;
|
|
||||||
|
|
||||||
private DatabaseDataModel Model = new();
|
private DatabaseDataModel Model = new();
|
||||||
|
|
||||||
@@ -122,7 +130,7 @@
|
|||||||
await LazyLoader.Reload();
|
await LazyLoader.Reload();
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task DeleteDatabase(Database database)
|
private async Task DeleteDatabase(MySqlDatabase database)
|
||||||
{
|
{
|
||||||
await WebSpaceService.DeleteDatabase(CurrentWebSpace, database);
|
await WebSpaceService.DeleteDatabase(CurrentWebSpace, database);
|
||||||
await LazyLoader.Reload();
|
await LazyLoader.Reload();
|
||||||
|
|||||||
@@ -34,8 +34,8 @@
|
|||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
<li class="nav-item mt-2">
|
<li class="nav-item mt-2">
|
||||||
<a class="nav-link text-active-primary ms-0 me-10 py-5 @(Index == 2 ? "active" : "")" href="/webspace/@(WebSpace.Id)/ftp">
|
<a class="nav-link text-active-primary ms-0 me-10 py-5 @(Index == 2 ? "active" : "")" href="/webspace/@(WebSpace.Id)/sftp">
|
||||||
<TL>Ftp</TL>
|
<TL>Sftp</TL>
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
<li class="nav-item mt-2">
|
<li class="nav-item mt-2">
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
<div class="mt-7 row fv-row mb-7">
|
<div class="mt-7 row fv-row mb-7">
|
||||||
<div class="col-md-3 text-md-start">
|
<div class="col-md-3 text-md-start">
|
||||||
<label class="fs-6 fw-semibold form-label mt-3">
|
<label class="fs-6 fw-semibold form-label mt-3">
|
||||||
<TL>Ftp Host</TL>
|
<TL>Sftp Host</TL>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-9">
|
<div class="col-md-9">
|
||||||
@@ -18,7 +18,7 @@
|
|||||||
<div class="row fv-row mb-7">
|
<div class="row fv-row mb-7">
|
||||||
<div class="col-md-3 text-md-start">
|
<div class="col-md-3 text-md-start">
|
||||||
<label class="fs-6 fw-semibold form-label mt-3">
|
<label class="fs-6 fw-semibold form-label mt-3">
|
||||||
<TL>Ftp Port</TL>
|
<TL>Sftp Port</TL>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-9">
|
<div class="col-md-9">
|
||||||
@@ -28,7 +28,7 @@
|
|||||||
<div class="row fv-row mb-7">
|
<div class="row fv-row mb-7">
|
||||||
<div class="col-md-3 text-md-start">
|
<div class="col-md-3 text-md-start">
|
||||||
<label class="fs-6 fw-semibold form-label mt-3">
|
<label class="fs-6 fw-semibold form-label mt-3">
|
||||||
<TL>Ftp Username</TL>
|
<TL>Sftp Username</TL>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-9">
|
<div class="col-md-9">
|
||||||
@@ -38,7 +38,7 @@
|
|||||||
<div class="row fv-row mb-7">
|
<div class="row fv-row mb-7">
|
||||||
<div class="col-md-3 text-md-start">
|
<div class="col-md-3 text-md-start">
|
||||||
<label class="fs-6 fw-semibold form-label mt-3">
|
<label class="fs-6 fw-semibold form-label mt-3">
|
||||||
<TL>Ftp Password</TL>
|
<TL>Sftp Password</TL>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-9">
|
<div class="col-md-9">
|
||||||
@@ -2,17 +2,18 @@
|
|||||||
@using Moonlight.App.Repositories.Servers
|
@using Moonlight.App.Repositories.Servers
|
||||||
@using Moonlight.App.Repositories
|
@using Moonlight.App.Repositories
|
||||||
@using Moonlight.App.Repositories.Domains
|
@using Moonlight.App.Repositories.Domains
|
||||||
|
@using Moonlight.App.Database.Entities
|
||||||
|
|
||||||
@inject ServerRepository ServerRepository
|
@inject ServerRepository ServerRepository
|
||||||
@inject UserRepository UserRepository
|
@inject UserRepository UserRepository
|
||||||
@inject WebsiteRepository WebsiteRepository
|
@inject Repository<WebSpace> WebSpaceRepository
|
||||||
@inject DomainRepository DomainRepository
|
@inject DomainRepository DomainRepository
|
||||||
|
|
||||||
<OnlyAdmin>
|
<OnlyAdmin>
|
||||||
<LazyLoader Load="Load">
|
<LazyLoader Load="Load">
|
||||||
<div class="row mb-5">
|
<div class="row mb-5">
|
||||||
<div class="col-12 col-lg-6 col-xl">
|
<div class="col-12 col-lg-6 col-xl">
|
||||||
<a class="mt-4 card" href="/servers">
|
<a class="mt-4 card" href="/admin/servers">
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<div class="row align-items-center gx-0">
|
<div class="row align-items-center gx-0">
|
||||||
<div class="col">
|
<div class="col">
|
||||||
@@ -38,10 +39,10 @@
|
|||||||
<div class="row align-items-center gx-0">
|
<div class="row align-items-center gx-0">
|
||||||
<div class="col">
|
<div class="col">
|
||||||
<h6 class="text-uppercase text-muted mb-2">
|
<h6 class="text-uppercase text-muted mb-2">
|
||||||
<TL>Websites</TL>
|
<TL>Webspaces</TL>
|
||||||
</h6>
|
</h6>
|
||||||
<span class="h2 mb-0">
|
<span class="h2 mb-0">
|
||||||
@(WebsiteCount)
|
@(WebSpaceCount)
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-auto">
|
<div class="col-auto">
|
||||||
@@ -54,7 +55,7 @@
|
|||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-12 col-lg-6 col-xl">
|
<div class="col-12 col-lg-6 col-xl">
|
||||||
<a class="mt-4 card" href="/domains">
|
<a class="mt-4 card" href="/admin/domains">
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<div class="row align-items-center gx-0">
|
<div class="row align-items-center gx-0">
|
||||||
<div class="col">
|
<div class="col">
|
||||||
@@ -75,7 +76,7 @@
|
|||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-12 col-lg-6 col-xl">
|
<div class="col-12 col-lg-6 col-xl">
|
||||||
<a class="mt-4 card" href="/domains">
|
<a class="mt-4 card" href="/admin/users">
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<div class="row align-items-center gx-0">
|
<div class="row align-items-center gx-0">
|
||||||
<div class="col">
|
<div class="col">
|
||||||
@@ -104,14 +105,14 @@
|
|||||||
private int ServerCount = 0;
|
private int ServerCount = 0;
|
||||||
private int UserCount = 0;
|
private int UserCount = 0;
|
||||||
private int DomainCount = 0;
|
private int DomainCount = 0;
|
||||||
private int WebsiteCount = 0;
|
private int WebSpaceCount = 0;
|
||||||
|
|
||||||
private Task Load(LazyLoader lazyLoader)
|
private Task Load(LazyLoader lazyLoader)
|
||||||
{
|
{
|
||||||
ServerCount = ServerRepository.Get().Count();
|
ServerCount = ServerRepository.Get().Count();
|
||||||
UserCount = UserRepository.Get().Count();
|
UserCount = UserRepository.Get().Count();
|
||||||
DomainCount = DomainRepository.Get().Count();
|
DomainCount = DomainRepository.Get().Count();
|
||||||
WebsiteCount = WebsiteRepository.Get().Count();
|
WebSpaceCount = WebSpaceRepository.Get().Count();
|
||||||
|
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -82,12 +82,12 @@
|
|||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-12 col-lg-6 col-xl">
|
<div class="col-12 col-lg-6 col-xl">
|
||||||
<a class="mt-4 card" href="/websites">
|
<a class="mt-4 card" href="/webspaces">
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<div class="row align-items-center gx-0">
|
<div class="row align-items-center gx-0">
|
||||||
<div class="col">
|
<div class="col">
|
||||||
<h6 class="text-uppercase text-muted mb-2">
|
<h6 class="text-uppercase text-muted mb-2">
|
||||||
<TL>Websites</TL>
|
<TL>Webspaces</TL>
|
||||||
</h6>
|
</h6>
|
||||||
<span class="h2 mb-0">
|
<span class="h2 mb-0">
|
||||||
@(WebsiteCount)
|
@(WebsiteCount)
|
||||||
|
|||||||
@@ -8,7 +8,6 @@
|
|||||||
|
|
||||||
@inject Repository<WebSpace> WebSpaceRepository
|
@inject Repository<WebSpace> WebSpaceRepository
|
||||||
@inject WebSpaceService WebSpaceService
|
@inject WebSpaceService WebSpaceService
|
||||||
@inject ToastService ToastService
|
|
||||||
|
|
||||||
<LazyLoader Load="Load">
|
<LazyLoader Load="Load">
|
||||||
@if (CurrentWebspace == null)
|
@if (CurrentWebspace == null)
|
||||||
@@ -40,7 +39,7 @@
|
|||||||
case "files":
|
case "files":
|
||||||
index = 1;
|
index = 1;
|
||||||
break;
|
break;
|
||||||
case "ftp":
|
case "sftp":
|
||||||
index = 2;
|
index = 2;
|
||||||
break;
|
break;
|
||||||
case "databases":
|
case "databases":
|
||||||
@@ -58,8 +57,8 @@
|
|||||||
case "files":
|
case "files":
|
||||||
<WebSpaceFiles />
|
<WebSpaceFiles />
|
||||||
break;
|
break;
|
||||||
case "ftp":
|
case "sftp":
|
||||||
<WebSpaceFtp />
|
<WebSpaceSftp />
|
||||||
break;
|
break;
|
||||||
case "databases":
|
case "databases":
|
||||||
<WebSpaceDatabases />
|
<WebSpaceDatabases />
|
||||||
|
|||||||
@@ -7,23 +7,23 @@
|
|||||||
|
|
||||||
@inject SubscriptionService SubscriptionService
|
@inject SubscriptionService SubscriptionService
|
||||||
@inject WebSpaceService WebSpaceService
|
@inject WebSpaceService WebSpaceService
|
||||||
@inject WebsiteRepository WebsiteRepository
|
@inject Repository<WebSpace> WebSpaceRepository
|
||||||
@inject SmartDeployService SmartDeployService
|
@inject SmartDeployService SmartDeployService
|
||||||
@inject SmartTranslateService SmartTranslateService
|
@inject SmartTranslateService SmartTranslateService
|
||||||
@inject NavigationManager NavigationManager
|
@inject NavigationManager NavigationManager
|
||||||
|
|
||||||
<LazyLoader Load="Load">
|
<LazyLoader Load="Load">
|
||||||
@if (PleskServer == null)
|
@if (CloudPanel == null)
|
||||||
{
|
{
|
||||||
<div class="d-flex justify-content-center flex-center">
|
<div class="d-flex justify-content-center flex-center">
|
||||||
<div class="card">
|
<div class="card">
|
||||||
<img src="/assets/media/svg/nodata.svg" class="card-img-top w-25 mx-auto pt-5" alt="Not found image"/>
|
<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">
|
<div class="card-body text-center">
|
||||||
<h4 class="card-title">
|
<h4 class="card-title">
|
||||||
<TL>No plesk server found</TL>
|
<TL>No web host found</TL>
|
||||||
</h4>
|
</h4>
|
||||||
<p class="card-text">
|
<p class="card-text">
|
||||||
<TL>No plesk server found to deploy to</TL>
|
<TL>No web host found to deploy to</TL>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -37,7 +37,7 @@
|
|||||||
<div class="card-header">
|
<div class="card-header">
|
||||||
<div class="card-title">
|
<div class="card-title">
|
||||||
<h2>
|
<h2>
|
||||||
<TL>Website details</TL>
|
<TL>Webspace details</TL>
|
||||||
</h2>
|
</h2>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -45,9 +45,9 @@
|
|||||||
<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">
|
<label class="form-label">
|
||||||
<TL>Plesk server</TL>
|
<TL>Web host</TL>
|
||||||
</label>
|
</label>
|
||||||
<div class="fw-bold fs-3">@(PleskServer.Name)</div>
|
<div class="fw-bold fs-3">@(CloudPanel.Name)</div>
|
||||||
</div>
|
</div>
|
||||||
@if (AllowOrder)
|
@if (AllowOrder)
|
||||||
{
|
{
|
||||||
@@ -67,7 +67,7 @@
|
|||||||
<div class="card-header">
|
<div class="card-header">
|
||||||
<div class="card-title">
|
<div class="card-title">
|
||||||
<h2>
|
<h2>
|
||||||
<TL>Configure your website</TL>
|
<TL>Configure your webspaces</TL>
|
||||||
</h2>
|
</h2>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -90,7 +90,7 @@
|
|||||||
{
|
{
|
||||||
<div class="alert alert-warning d-flex align-items-center p-5 mb-10">
|
<div class="alert alert-warning d-flex align-items-center p-5 mb-10">
|
||||||
<span>
|
<span>
|
||||||
<TL>You reached the maximum amount of websites in your subscription</TL>: @(Subscription == null ? SmartTranslateService.Translate("Default") : Subscription.Name)
|
<TL>You reached the maximum amount of webspaces in your subscription</TL>: @(Subscription == null ? SmartTranslateService.Translate("Default") : Subscription.Name)
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
@@ -108,7 +108,7 @@
|
|||||||
public User User { get; set; }
|
public User User { get; set; }
|
||||||
|
|
||||||
private Subscription? Subscription;
|
private Subscription? Subscription;
|
||||||
private PleskServer? PleskServer;
|
private CloudPanel? CloudPanel;
|
||||||
private bool AllowOrder = false;
|
private bool AllowOrder = false;
|
||||||
|
|
||||||
private WebsiteOrderDataModel Model = new();
|
private WebsiteOrderDataModel Model = new();
|
||||||
@@ -121,10 +121,10 @@
|
|||||||
await lazyLoader.SetText(SmartTranslateService.Translate("Loading your subscription"));
|
await lazyLoader.SetText(SmartTranslateService.Translate("Loading your subscription"));
|
||||||
Subscription = await SubscriptionService.GetCurrent();
|
Subscription = await SubscriptionService.GetCurrent();
|
||||||
|
|
||||||
await lazyLoader.SetText(SmartTranslateService.Translate("Searching for deploy plesk server"));
|
await lazyLoader.SetText(SmartTranslateService.Translate("Searching for deploy web host"));
|
||||||
PleskServer = await SmartDeployService.GetPleskServer();
|
CloudPanel = await SmartDeployService.GetCloudPanel();
|
||||||
|
|
||||||
AllowOrder = WebsiteRepository
|
AllowOrder = WebSpaceRepository
|
||||||
.Get()
|
.Get()
|
||||||
.Include(x => x.Owner)
|
.Include(x => x.Owner)
|
||||||
.Count(x => x.Owner.Id == User.Id) < (await SubscriptionService.GetLimit("websites")).Amount;
|
.Count(x => x.Owner.Id == User.Id) < (await SubscriptionService.GetLimit("websites")).Amount;
|
||||||
@@ -132,14 +132,14 @@
|
|||||||
|
|
||||||
private async Task OnValidSubmit()
|
private async Task OnValidSubmit()
|
||||||
{
|
{
|
||||||
if (WebsiteRepository
|
if (WebSpaceRepository
|
||||||
.Get()
|
.Get()
|
||||||
.Include(x => x.Owner)
|
.Include(x => x.Owner)
|
||||||
.Count(x => x.Owner.Id == User.Id) < (await SubscriptionService.GetLimit("websites")).Amount)
|
.Count(x => x.Owner.Id == User.Id) < (await SubscriptionService.GetLimit("websites")).Amount)
|
||||||
{
|
{
|
||||||
//var website = await WebsiteService.Create(Model.BaseDomain, User, PleskServer);
|
var webSpace = await WebSpaceService.Create(Model.BaseDomain, User, CloudPanel);
|
||||||
|
|
||||||
//NavigationManager.NavigateTo($"/website/{website.Id}");
|
NavigationManager.NavigateTo($"/webspace/{webSpace.Id}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user