fix #1640 to resolve issue with server prerendering, upgrade Installer to Bootstrap5, add more defensive logic and logging to DatabaseManager, fix file logger issue, update Pager to use Bootstrap5 pagination, add expiry date support for commercial extensions
This commit is contained in:
parent
07165ce68d
commit
53e5728ad2
|
@ -33,23 +33,26 @@
|
||||||
|
|
||||||
private PageState PageState { get; set; }
|
private PageState PageState { get; set; }
|
||||||
|
|
||||||
|
protected override async Task OnParametersSetAsync()
|
||||||
|
{
|
||||||
|
_installation = await InstallationService.IsInstalled();
|
||||||
|
if (_installation.Alias != null)
|
||||||
|
{
|
||||||
|
SiteState.Alias = _installation.Alias;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_installation.Message = "Site Not Configured Correctly - No Matching Alias Exists For Host Name";
|
||||||
|
}
|
||||||
|
_initialized = true;
|
||||||
|
}
|
||||||
|
|
||||||
protected override async Task OnAfterRenderAsync(bool firstRender)
|
protected override async Task OnAfterRenderAsync(bool firstRender)
|
||||||
{
|
{
|
||||||
if (firstRender && !_initialized)
|
if (firstRender)
|
||||||
{
|
{
|
||||||
var interop = new Interop(JSRuntime);
|
var interop = new Interop(JSRuntime);
|
||||||
SiteState.AntiForgeryToken = await interop.GetElementByName(Constants.RequestVerificationToken);
|
SiteState.AntiForgeryToken = await interop.GetElementByName(Constants.RequestVerificationToken);
|
||||||
_installation = await InstallationService.IsInstalled();
|
|
||||||
if (_installation.Alias != null)
|
|
||||||
{
|
|
||||||
SiteState.Alias = _installation.Alias;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_installation.Message = "Site Not Configured Correctly - No Matching Alias Exists For Host Name";
|
|
||||||
}
|
|
||||||
_initialized = true;
|
|
||||||
StateHasChanged();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -150,7 +150,8 @@
|
||||||
if (firstRender)
|
if (firstRender)
|
||||||
{
|
{
|
||||||
var interop = new Interop(JSRuntime);
|
var interop = new Interop(JSRuntime);
|
||||||
await interop.IncludeLink("app-stylesheet", "stylesheet", "https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css", "text/css", "sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T", "anonymous", "");
|
await interop.IncludeLink("", "stylesheet", "https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css", "text/css", "sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC", "anonymous", "");
|
||||||
|
await interop.IncludeScript("", "https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js", "sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM", "anonymous", "", "head", "");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -32,10 +32,6 @@ else
|
||||||
{
|
{
|
||||||
<button type="button" class="btn btn-success" @onclick=@(async () => await DownloadLanguage(context.Code))>@SharedLocalizer["Upgrade"]</button>
|
<button type="button" class="btn btn-success" @onclick=@(async () => await DownloadLanguage(context.Code))>@SharedLocalizer["Upgrade"]</button>
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
@((MarkupString)PurchaseLink(context.Code))
|
|
||||||
}
|
|
||||||
</td>
|
</td>
|
||||||
</Row>
|
</Row>
|
||||||
</Pager>
|
</Pager>
|
||||||
|
@ -95,23 +91,6 @@ else
|
||||||
return upgradeavailable;
|
return upgradeavailable;
|
||||||
}
|
}
|
||||||
|
|
||||||
private string PurchaseLink(string code)
|
|
||||||
{
|
|
||||||
string link = "";
|
|
||||||
if (_packages != null)
|
|
||||||
{
|
|
||||||
var package = _packages.Where(item => item.PackageId == (Constants.PackageId + ".Client." + code)).FirstOrDefault();
|
|
||||||
if (package != null)
|
|
||||||
{
|
|
||||||
if (package.Price > 0 && !string.IsNullOrEmpty(package.PaymentUrl))
|
|
||||||
{
|
|
||||||
link = "<a class=\"btn btn-primary\" style=\"text-decoration: none !important\" href=\"" + package.PaymentUrl + "\" target=\"_new\">" + package.Price.ToString("$#,##0.00") + "</a>";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return link;
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task DownloadLanguage(string code)
|
private async Task DownloadLanguage(string code)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
|
|
@ -22,27 +22,27 @@ else
|
||||||
<th style="width: 1px;"> </th>
|
<th style="width: 1px;"> </th>
|
||||||
<th>@SharedLocalizer["Name"]</th>
|
<th>@SharedLocalizer["Name"]</th>
|
||||||
<th>@SharedLocalizer["Version"]</th>
|
<th>@SharedLocalizer["Version"]</th>
|
||||||
|
<th>@SharedLocalizer["Expires"]</th>
|
||||||
<th style="width: 1px;"> </th>
|
<th style="width: 1px;"> </th>
|
||||||
</Header>
|
</Header>
|
||||||
<Row>
|
<Row>
|
||||||
<td><ActionLink Action="Edit" Parameters="@($"id=" + context.ModuleDefinitionId.ToString())" ResourceKey="EditModule" /></td>
|
<td><ActionLink Action="Edit" Parameters="@($"id=" + context.ModuleDefinitionId.ToString())" ResourceKey="EditModule" /></td>
|
||||||
<td>
|
<td>
|
||||||
@if (context.AssemblyName != "Oqtane.Client")
|
@if (context.AssemblyName != "Oqtane.Client")
|
||||||
{
|
{
|
||||||
<ActionDialog Header="Delete Module" Message="@string.Format(Localizer["Confirm.Module.Delete", context.Name])" Action="Delete" Security="SecurityAccessLevel.Host" Class="btn btn-danger" OnClick="@(async () => await DeleteModule(context))" ResourceKey="DeleteModule" />
|
<ActionDialog Header="Delete Module" Message="@string.Format(Localizer["Confirm.Module.Delete", context.Name])" Action="Delete" Security="SecurityAccessLevel.Host" Class="btn btn-danger" OnClick="@(async () => await DeleteModule(context))" ResourceKey="DeleteModule" />
|
||||||
}
|
}
|
||||||
</td>
|
</td>
|
||||||
<td>@context.Name</td>
|
<td>@context.Name</td>
|
||||||
<td>@context.Version</td>
|
<td>@context.Version</td>
|
||||||
|
<td>
|
||||||
|
@((MarkupString)PurchaseLink(context.PackageName))
|
||||||
|
</td>
|
||||||
<td>
|
<td>
|
||||||
@if (UpgradeAvailable(context.PackageName, context.Version))
|
@if (UpgradeAvailable(context.PackageName, context.Version))
|
||||||
{
|
{
|
||||||
<button type="button" class="btn btn-success" @onclick=@(async () => await DownloadModule(context.PackageName, context.Version))>@SharedLocalizer["Upgrade"]</button>
|
<button type="button" class="btn btn-success" @onclick=@(async () => await DownloadModule(context.PackageName, context.Version))>@SharedLocalizer["Upgrade"]</button>
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
@((MarkupString)PurchaseLink(context.PackageName))
|
|
||||||
}
|
|
||||||
</td>
|
</td>
|
||||||
</Row>
|
</Row>
|
||||||
</Pager>
|
</Pager>
|
||||||
|
@ -71,6 +71,27 @@ else
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private string PurchaseLink(string packagename)
|
||||||
|
{
|
||||||
|
string link = "";
|
||||||
|
if (!string.IsNullOrEmpty(packagename) && _packages != null)
|
||||||
|
{
|
||||||
|
var package = _packages.Where(item => item.PackageId == packagename).FirstOrDefault();
|
||||||
|
if (package != null)
|
||||||
|
{
|
||||||
|
if (package.ExpiryDate != null && package.ExpiryDate.Value.Date != DateTime.MaxValue.Date)
|
||||||
|
{
|
||||||
|
link += "<span>" + package.ExpiryDate.Value.Date.ToString("MMM dd, yyyy") + "</span>";
|
||||||
|
if (!string.IsNullOrEmpty(package.PaymentUrl))
|
||||||
|
{
|
||||||
|
link += " <a class=\"btn btn-primary\" style=\"text-decoration: none !important\" href=\"" + package.PaymentUrl + "\" target=\"_new\">" + SharedLocalizer["Extend"] + "</a>";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return link;
|
||||||
|
}
|
||||||
|
|
||||||
private bool UpgradeAvailable(string packagename, string version)
|
private bool UpgradeAvailable(string packagename, string version)
|
||||||
{
|
{
|
||||||
var upgradeavailable = false;
|
var upgradeavailable = false;
|
||||||
|
@ -86,23 +107,6 @@ else
|
||||||
return upgradeavailable;
|
return upgradeavailable;
|
||||||
}
|
}
|
||||||
|
|
||||||
private string PurchaseLink(string packagename)
|
|
||||||
{
|
|
||||||
string link = "";
|
|
||||||
if (!string.IsNullOrEmpty(packagename) && _packages != null)
|
|
||||||
{
|
|
||||||
var package = _packages.Where(item => item.PackageId == packagename).FirstOrDefault();
|
|
||||||
if (package != null)
|
|
||||||
{
|
|
||||||
if (package.Price > 0 && !string.IsNullOrEmpty(package.PaymentUrl))
|
|
||||||
{
|
|
||||||
link = "<a class=\"btn btn-primary\" style=\"text-decoration: none !important\" href=\"" + package.PaymentUrl + "\" target=\"_new\">" + package.Price.ToString("$#,##0.00") + "</a>";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return link;
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task DownloadModule(string packagename, string version)
|
private async Task DownloadModule(string packagename, string version)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
|
|
@ -44,12 +44,6 @@
|
||||||
<input id="installationid" class="form-control" @bind="@_installationid" readonly />
|
<input id="installationid" class="form-control" @bind="@_installationid" readonly />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row mb-1 align-items-center">
|
|
||||||
<div class="col-sm-3"></div>
|
|
||||||
<div class="col-sm-9">
|
|
||||||
<br /><input type="checkbox" @onchange="(e => RegisterChecked(e))" /> @Localizer["Register"]
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<br /><br />
|
<br /><br />
|
||||||
<ActionDialog Header="Restart Application" Message="Are You Sure You Wish To Restart The Application?" Action="Restart Application" Security="SecurityAccessLevel.Host" Class="btn btn-danger" OnClick="@(async () => await RestartApplication())" ResourceKey="RestartApplication" />
|
<ActionDialog Header="Restart Application" Message="Are You Sure You Wish To Restart The Application?" Action="Restart Application" Security="SecurityAccessLevel.Host" Class="btn btn-danger" OnClick="@(async () => await RestartApplication())" ResourceKey="RestartApplication" />
|
||||||
|
@ -196,20 +190,4 @@
|
||||||
await logger.LogError(ex, "Error Restarting Application");
|
await logger.LogError(ex, "Error Restarting Application");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task RegisterChecked(ChangeEventArgs e)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if ((bool)e.Value)
|
|
||||||
{
|
|
||||||
await InstallationService.RegisterAsync(PageState.User.Email);
|
|
||||||
AddModuleMessage(Localizer["Success.Register"], MessageType.Success);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
await logger.LogError(ex, "Error On Register");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
|
@ -21,29 +21,29 @@ else
|
||||||
<Header>
|
<Header>
|
||||||
<th style="width: 1px;"> </th>
|
<th style="width: 1px;"> </th>
|
||||||
<th style="width: 1px;"> </th>
|
<th style="width: 1px;"> </th>
|
||||||
<th scope="col">@SharedLocalizer["Name"]</th>
|
<th>@SharedLocalizer["Name"]</th>
|
||||||
<th scope="col">@SharedLocalizer["Version"]</th>
|
<th>@SharedLocalizer["Version"]</th>
|
||||||
|
<th>@SharedLocalizer["Expires"]</th>
|
||||||
<th> </th>
|
<th> </th>
|
||||||
</Header>
|
</Header>
|
||||||
<Row>
|
<Row>
|
||||||
<td><ActionLink Action="View" Parameters="@($"name=" + WebUtility.UrlEncode(context.ThemeName))" ResourceKey="ViewTheme" /></td>
|
<td><ActionLink Action="View" Parameters="@($"name=" + WebUtility.UrlEncode(context.ThemeName))" ResourceKey="ViewTheme" /></td>
|
||||||
<td>
|
<td>
|
||||||
@if (context.AssemblyName != "Oqtane.Client")
|
@if (context.AssemblyName != "Oqtane.Client")
|
||||||
{
|
{
|
||||||
<ActionDialog Header="Delete Theme" Message="@string.Format(Localizer["Confirm.Theme.Delete"], context.Name)" Action="Delete" Security="SecurityAccessLevel.Host" Class="btn btn-danger" OnClick="@(async () => await DeleteTheme(context))" ResourceKey="DeleteTheme" />
|
<ActionDialog Header="Delete Theme" Message="@string.Format(Localizer["Confirm.Theme.Delete"], context.Name)" Action="Delete" Security="SecurityAccessLevel.Host" Class="btn btn-danger" OnClick="@(async () => await DeleteTheme(context))" ResourceKey="DeleteTheme" />
|
||||||
}
|
}
|
||||||
</td>
|
</td>
|
||||||
<td>@context.Name</td>
|
<td>@context.Name</td>
|
||||||
<td>@context.Version</td>
|
<td>@context.Version</td>
|
||||||
|
<td>
|
||||||
|
@((MarkupString)PurchaseLink(context.PackageName))
|
||||||
|
</td>
|
||||||
<td>
|
<td>
|
||||||
@if (UpgradeAvailable(context.PackageName, context.Version))
|
@if (UpgradeAvailable(context.PackageName, context.Version))
|
||||||
{
|
{
|
||||||
<button type="button" class="btn btn-success" @onclick=@(async () => await DownloadTheme(context.PackageName, context.Version))>@SharedLocalizer["Upgrade"]</button>
|
<button type="button" class="btn btn-success" @onclick=@(async () => await DownloadTheme(context.PackageName, context.Version))>@SharedLocalizer["Upgrade"]</button>
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
@((MarkupString)PurchaseLink(context.PackageName))
|
|
||||||
}
|
|
||||||
</td>
|
</td>
|
||||||
<td></td>
|
<td></td>
|
||||||
</Row>
|
</Row>
|
||||||
|
@ -73,6 +73,27 @@ else
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private string PurchaseLink(string packagename)
|
||||||
|
{
|
||||||
|
string link = "";
|
||||||
|
if (!string.IsNullOrEmpty(packagename) && _packages != null)
|
||||||
|
{
|
||||||
|
var package = _packages.Where(item => item.PackageId == packagename).FirstOrDefault();
|
||||||
|
if (package != null)
|
||||||
|
{
|
||||||
|
if (package.ExpiryDate != null && package.ExpiryDate.Value.Date != DateTime.MaxValue.Date)
|
||||||
|
{
|
||||||
|
link += "<span>" + package.ExpiryDate.Value.Date.ToString("MMM dd, yyyy") + "</span>";
|
||||||
|
if (!string.IsNullOrEmpty(package.PaymentUrl))
|
||||||
|
{
|
||||||
|
link += " <a class=\"btn btn-primary\" style=\"text-decoration: none !important\" href=\"" + package.PaymentUrl + "\" target=\"_new\">" + SharedLocalizer["Extend"] + "</a>";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return link;
|
||||||
|
}
|
||||||
|
|
||||||
private bool UpgradeAvailable(string packagename, string version)
|
private bool UpgradeAvailable(string packagename, string version)
|
||||||
{
|
{
|
||||||
var upgradeavailable = false;
|
var upgradeavailable = false;
|
||||||
|
@ -103,23 +124,6 @@ else
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private string PurchaseLink(string packagename)
|
|
||||||
{
|
|
||||||
string link = "";
|
|
||||||
if (!string.IsNullOrEmpty(packagename) && _packages != null)
|
|
||||||
{
|
|
||||||
var package = _packages.Where(item => item.PackageId == packagename).FirstOrDefault();
|
|
||||||
if (package != null)
|
|
||||||
{
|
|
||||||
if (package.Price > 0 && !string.IsNullOrEmpty(package.PaymentUrl))
|
|
||||||
{
|
|
||||||
link = "<a class=\"btn btn-primary\" style=\"text-decoration: none !important\" href=\"" + package.PaymentUrl + "\" target=\"_new\">" + package.Price.ToString("$#,##0.00") + "</a>";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return link;
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task DeleteTheme(Theme Theme)
|
private async Task DeleteTheme(Theme Theme)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
|
|
@ -5,40 +5,63 @@
|
||||||
<p>
|
<p>
|
||||||
@if (Toolbar == "Top")
|
@if (Toolbar == "Top")
|
||||||
{
|
{
|
||||||
<div class="mx-auto text-center">
|
<ul class="pagination justify-content-center my-2">
|
||||||
@if (_endPage > 1)
|
@if (_endPage > 1)
|
||||||
{
|
{
|
||||||
<button class="btn btn-secondary m-1" @onclick=@(async () => UpdateList(1))><span class="oi oi-media-step-backward" title="first" aria-hidden="true"></span></button>
|
<li class="page-item">
|
||||||
|
<a class="page-link" @onclick=@(async () => UpdateList(1))><span class="oi oi-media-step-backward" title="first" aria-hidden="true"></span></a>
|
||||||
|
</li>
|
||||||
}
|
}
|
||||||
@if (_page > _maxPages)
|
@if (_page > _maxPages)
|
||||||
{
|
{
|
||||||
<button class="btn btn-secondary m-1" @onclick=@(async () => SetPagerSize("back"))><span class="oi oi-media-skip-backward" title="back" aria-hidden="true"></span></button>
|
<li class="page-item">
|
||||||
|
<a class="page-link" @onclick=@(async () => SetPagerSize("back"))><span class="oi oi-media-skip-backward" title="back" aria-hidden="true"></span></a>
|
||||||
|
</li>
|
||||||
}
|
}
|
||||||
@if (_endPage > 1)
|
@if (_endPage > 1)
|
||||||
{
|
{
|
||||||
<button class="btn btn-secondary m-1" @onclick=@(async () => NavigateToPage("previous"))><span class="oi oi-chevron-left" title="previous" aria-hidden="true"></span></button>
|
<li class="page-item">
|
||||||
|
<a class="page-link" @onclick=@(async () => NavigateToPage("previous"))><span class="oi oi-chevron-left" title="previous" aria-hidden="true"></span></a>
|
||||||
|
</li>
|
||||||
@for (int i = _startPage; i <= _endPage; i++)
|
@for (int i = _startPage; i <= _endPage; i++)
|
||||||
{
|
{
|
||||||
var pager = i;
|
var pager = i;
|
||||||
<button class="btn @((pager == _page) ? "btn-primary" : "btn-link")" @onclick=@(async () => UpdateList(pager))>
|
if (pager == _page)
|
||||||
@pager
|
{
|
||||||
</button>
|
<li class="page-item active">
|
||||||
|
<a class="page-link" @onclick=@(async () => UpdateList(pager))>@pager</a>
|
||||||
|
</li>
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
<li class="page-item">
|
||||||
|
<a class="page-link" @onclick=@(async () => UpdateList(pager))>@pager</a>
|
||||||
|
</li>
|
||||||
|
}
|
||||||
}
|
}
|
||||||
<button class="btn btn-secondary m-1" @onclick=@(async () => NavigateToPage("next"))><span class="oi oi-chevron-right" title="next" aria-hidden="true"></span></button>
|
<li class="page-item">
|
||||||
|
<a class="page-link" @onclick=@(async () => NavigateToPage("next"))><span class="oi oi-chevron-right" title="next" aria-hidden="true"></span></a>
|
||||||
|
</li>
|
||||||
}
|
}
|
||||||
@if (_endPage < _pages)
|
@if (_endPage < _pages)
|
||||||
{
|
{
|
||||||
<button class="btn btn-secondary m-1" @onclick=@(async () => SetPagerSize("forward"))><span class="oi oi-media-skip-forward" title="forward" aria-hidden="true"></span></button>
|
<li class="page-item">
|
||||||
|
<a class="page-link" @onclick=@(async () => SetPagerSize("forward"))><span class="oi oi-media-skip-forward" title="forward" aria-hidden="true"></span></a>
|
||||||
|
</li>
|
||||||
}
|
}
|
||||||
@if (_endPage > 1)
|
@if (_endPage > 1)
|
||||||
{
|
{
|
||||||
<button class="btn btn-secondary m-1" @onclick=@(async () => UpdateList(_pages))><span class="oi oi-media-step-forward" title="last" aria-hidden="true"></span></button>
|
<li class="page-item">
|
||||||
|
<a class="page-link" @onclick=@(async () => UpdateList(_pages))><span class="oi oi-media-step-forward" title="last" aria-hidden="true"></span></a>
|
||||||
|
</li>
|
||||||
}
|
}
|
||||||
@if (_endPage > 1)
|
@if (_endPage > 1)
|
||||||
{
|
{
|
||||||
<span class="btn btn-link disabled">Page @_page of @_pages</span>
|
<li class="page-item disabled">
|
||||||
|
<a class="page-link">Page @_page of @_pages</a>
|
||||||
|
</li>
|
||||||
}
|
}
|
||||||
</div>
|
</ul>
|
||||||
}
|
}
|
||||||
@if (Format == "Table")
|
@if (Format == "Table")
|
||||||
{
|
{
|
||||||
|
@ -74,40 +97,63 @@
|
||||||
}
|
}
|
||||||
@if (Toolbar == "Bottom")
|
@if (Toolbar == "Bottom")
|
||||||
{
|
{
|
||||||
<div class="mx-auto text-center">
|
<ul class="pagination justify-content-center my-2">
|
||||||
@if (_endPage > 1)
|
@if (_endPage > 1)
|
||||||
{
|
{
|
||||||
<button class="btn btn-secondary mr-1" @onclick=@(async () => UpdateList(1))><span class="oi oi-media-step-backward" title="first" aria-hidden="true"></span></button>
|
<li class="page-item">
|
||||||
|
<a class="page-link" @onclick=@(async () => UpdateList(1))><span class="oi oi-media-step-backward" title="first" aria-hidden="true"></span></a>
|
||||||
|
</li>
|
||||||
}
|
}
|
||||||
@if (_page > _maxPages)
|
@if (_page > _maxPages)
|
||||||
{
|
{
|
||||||
<button class="btn btn-secondary mr-1" @onclick=@(async () => SetPagerSize("back"))><span class="oi oi-media-skip-backward" title="back" aria-hidden="true"></span></button>
|
<li class="page-item">
|
||||||
|
<a class="page-link" @onclick=@(async () => SetPagerSize("back"))><span class="oi oi-media-skip-backward" title="back" aria-hidden="true"></span></a>
|
||||||
|
</li>
|
||||||
}
|
}
|
||||||
@if (_endPage > 1)
|
@if (_endPage > 1)
|
||||||
{
|
{
|
||||||
<button class="btn btn-secondary mr-1" @onclick=@(async () => NavigateToPage("previous"))><span class="oi oi-chevron-left" title="previous" aria-hidden="true"></span></button>
|
<li class="page-item">
|
||||||
|
<a class="page-link" @onclick=@(async () => NavigateToPage("previous"))><span class="oi oi-chevron-left" title="previous" aria-hidden="true"></span></a>
|
||||||
|
</li>
|
||||||
@for (int i = _startPage; i <= _endPage; i++)
|
@for (int i = _startPage; i <= _endPage; i++)
|
||||||
{
|
{
|
||||||
var pager = i;
|
var pager = i;
|
||||||
<button class="btn @((pager == _page) ? "btn-primary" : "btn-link")" @onclick=@(async () => UpdateList(pager))>
|
if (pager == _page)
|
||||||
@pager
|
{
|
||||||
</button>
|
<li class="page-item active">
|
||||||
|
<a class="page-link" @onclick=@(async () => UpdateList(pager))>@pager</a>
|
||||||
|
</li>
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
<li class="page-item">
|
||||||
|
<a class="page-link" @onclick=@(async () => UpdateList(pager))>@pager</a>
|
||||||
|
</li>
|
||||||
|
}
|
||||||
}
|
}
|
||||||
<button class="btn btn-secondary mr-1" @onclick=@(async () => NavigateToPage("next"))><span class="oi oi-chevron-right" title="next" aria-hidden="true"></span></button>
|
<li class="page-item">
|
||||||
|
<a class="page-link" @onclick=@(async () => NavigateToPage("next"))><span class="oi oi-chevron-right" title="next" aria-hidden="true"></span></a>
|
||||||
|
</li>
|
||||||
}
|
}
|
||||||
@if (_endPage < _pages)
|
@if (_endPage < _pages)
|
||||||
{
|
{
|
||||||
<button class="btn btn-secondary mr-1" @onclick=@(async () => SetPagerSize("forward"))><span class="oi oi-media-skip-forward" title="forward" aria-hidden="true"></span></button>
|
<li class="page-item">
|
||||||
|
<a class="page-link" @onclick=@(async () => SetPagerSize("forward"))><span class="oi oi-media-skip-forward" title="forward" aria-hidden="true"></span></a>
|
||||||
|
</li>
|
||||||
}
|
}
|
||||||
@if (_endPage > 1)
|
@if (_endPage > 1)
|
||||||
{
|
{
|
||||||
<button class="btn btn-secondary mr-1" @onclick=@(async () => UpdateList(_pages))><span class="oi oi-media-step-forward" title="last" aria-hidden="true"></span></button>
|
<li class="page-item">
|
||||||
|
<a class="page-link" @onclick=@(async () => UpdateList(_pages))><span class="oi oi-media-step-forward" title="last" aria-hidden="true"></span></a>
|
||||||
|
</li>
|
||||||
}
|
}
|
||||||
@if (_endPage > 1)
|
@if (_endPage > 1)
|
||||||
{
|
{
|
||||||
<span class="btn btn-link disabled">Page @_page of @_pages</span>
|
<li class="page-item disabled">
|
||||||
|
<a class="page-link">Page @_page of @_pages</a>
|
||||||
|
</li>
|
||||||
}
|
}
|
||||||
</div>
|
</ul>
|
||||||
}
|
}
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
|
|
@ -303,4 +303,10 @@
|
||||||
<data name="Trial" xml:space="preserve">
|
<data name="Trial" xml:space="preserve">
|
||||||
<value>Day Trial</value>
|
<value>Day Trial</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="Expires" xml:space="preserve">
|
||||||
|
<value>Expires</value>
|
||||||
|
</data>
|
||||||
|
<data name="Extend" xml:space="preserve">
|
||||||
|
<value>Extend</value>
|
||||||
|
</data>
|
||||||
</root>
|
</root>
|
|
@ -250,6 +250,7 @@ namespace Oqtane.Infrastructure
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
result.Message = ex.Message;
|
result.Message = ex.Message;
|
||||||
|
_filelogger.LogError(Utilities.LogMessage(this, result.Message));
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
@ -288,6 +289,7 @@ namespace Oqtane.Infrastructure
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
result.Message = ex.Message;
|
result.Message = ex.Message;
|
||||||
|
_filelogger.LogError(Utilities.LogMessage(this, result.Message));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -328,6 +330,7 @@ namespace Oqtane.Infrastructure
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
result.Message = ex.Message;
|
result.Message = ex.Message;
|
||||||
|
_filelogger.LogError(Utilities.LogMessage(this, result.Message));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -432,6 +435,7 @@ namespace Oqtane.Infrastructure
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
result.Message = ex.Message;
|
result.Message = ex.Message;
|
||||||
|
_filelogger.LogError(Utilities.LogMessage(this, result.Message));
|
||||||
}
|
}
|
||||||
|
|
||||||
// execute any version specific upgrade logic
|
// execute any version specific upgrade logic
|
||||||
|
@ -539,6 +543,10 @@ namespace Oqtane.Infrastructure
|
||||||
{
|
{
|
||||||
result.Success = true;
|
result.Success = true;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_filelogger.LogError(Utilities.LogMessage(this, result.Message));
|
||||||
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -549,110 +557,124 @@ namespace Oqtane.Infrastructure
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(install.TenantName) && !string.IsNullOrEmpty(install.Aliases) && !string.IsNullOrEmpty(install.SiteName))
|
if (!string.IsNullOrEmpty(install.TenantName) && !string.IsNullOrEmpty(install.Aliases) && !string.IsNullOrEmpty(install.SiteName))
|
||||||
{
|
{
|
||||||
using (var scope = _serviceScopeFactory.CreateScope())
|
try
|
||||||
{
|
{
|
||||||
// set the alias explicitly so the tenant can be resolved
|
using (var scope = _serviceScopeFactory.CreateScope())
|
||||||
var aliases = scope.ServiceProvider.GetRequiredService<IAliasRepository>();
|
|
||||||
var firstAlias = install.Aliases.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries)[0];
|
|
||||||
var alias = aliases.GetAliases().FirstOrDefault(item => item.Name == firstAlias);
|
|
||||||
var tenantManager = scope.ServiceProvider.GetRequiredService<ITenantManager>();
|
|
||||||
tenantManager.SetAlias(alias);
|
|
||||||
|
|
||||||
var sites = scope.ServiceProvider.GetRequiredService<ISiteRepository>();
|
|
||||||
var site = sites.GetSites().FirstOrDefault(item => item.Name == install.SiteName);
|
|
||||||
if (site == null)
|
|
||||||
{
|
{
|
||||||
var tenants = scope.ServiceProvider.GetRequiredService<ITenantRepository>();
|
// set the alias explicitly so the tenant can be resolved
|
||||||
var users = scope.ServiceProvider.GetRequiredService<IUserRepository>();
|
var aliases = scope.ServiceProvider.GetRequiredService<IAliasRepository>();
|
||||||
var roles = scope.ServiceProvider.GetRequiredService<IRoleRepository>();
|
var firstAlias = install.Aliases.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries)[0];
|
||||||
var userRoles = scope.ServiceProvider.GetRequiredService<IUserRoleRepository>();
|
var alias = aliases.GetAliases().FirstOrDefault(item => item.Name == firstAlias);
|
||||||
var folders = scope.ServiceProvider.GetRequiredService<IFolderRepository>();
|
var tenantManager = scope.ServiceProvider.GetRequiredService<ITenantManager>();
|
||||||
var log = scope.ServiceProvider.GetRequiredService<ILogManager>();
|
tenantManager.SetAlias(alias);
|
||||||
var identityUserManager = scope.ServiceProvider.GetRequiredService<UserManager<IdentityUser>>();
|
|
||||||
|
|
||||||
var tenant = tenants.GetTenants().FirstOrDefault(item => item.Name == install.TenantName);
|
var sites = scope.ServiceProvider.GetRequiredService<ISiteRepository>();
|
||||||
|
var site = sites.GetSites().FirstOrDefault(item => item.Name == install.SiteName);
|
||||||
site = new Site
|
if (site == null)
|
||||||
{
|
{
|
||||||
TenantId = tenant.TenantId,
|
var tenants = scope.ServiceProvider.GetRequiredService<ITenantRepository>();
|
||||||
Name = install.SiteName,
|
var users = scope.ServiceProvider.GetRequiredService<IUserRepository>();
|
||||||
LogoFileId = null,
|
var roles = scope.ServiceProvider.GetRequiredService<IRoleRepository>();
|
||||||
DefaultThemeType = (!string.IsNullOrEmpty(install.DefaultTheme)) ? install.DefaultTheme : Constants.DefaultTheme,
|
var userRoles = scope.ServiceProvider.GetRequiredService<IUserRoleRepository>();
|
||||||
DefaultContainerType = (!string.IsNullOrEmpty(install.DefaultContainer)) ? install.DefaultContainer : Constants.DefaultContainer,
|
var folders = scope.ServiceProvider.GetRequiredService<IFolderRepository>();
|
||||||
AdminContainerType = (!string.IsNullOrEmpty(install.DefaultAdminContainer)) ? install.DefaultAdminContainer : Constants.DefaultAdminContainer,
|
var log = scope.ServiceProvider.GetRequiredService<ILogManager>();
|
||||||
SiteTemplateType = install.SiteTemplate
|
var identityUserManager = scope.ServiceProvider.GetRequiredService<UserManager<IdentityUser>>();
|
||||||
};
|
|
||||||
site = sites.AddSite(site);
|
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(install.HostUsername))
|
var tenant = tenants.GetTenants().FirstOrDefault(item => item.Name == install.TenantName);
|
||||||
{
|
|
||||||
var identityUser = identityUserManager.FindByNameAsync(install.HostUsername).GetAwaiter().GetResult();
|
site = new Site
|
||||||
if (identityUser == null)
|
|
||||||
{
|
{
|
||||||
identityUser = new IdentityUser { UserName = install.HostUsername, Email = install.HostEmail, EmailConfirmed = true };
|
TenantId = tenant.TenantId,
|
||||||
var create = identityUserManager.CreateAsync(identityUser, install.HostPassword).GetAwaiter().GetResult();
|
Name = install.SiteName,
|
||||||
if (create.Succeeded)
|
LogoFileId = null,
|
||||||
|
DefaultThemeType = (!string.IsNullOrEmpty(install.DefaultTheme)) ? install.DefaultTheme : Constants.DefaultTheme,
|
||||||
|
DefaultContainerType = (!string.IsNullOrEmpty(install.DefaultContainer)) ? install.DefaultContainer : Constants.DefaultContainer,
|
||||||
|
AdminContainerType = (!string.IsNullOrEmpty(install.DefaultAdminContainer)) ? install.DefaultAdminContainer : Constants.DefaultAdminContainer,
|
||||||
|
SiteTemplateType = install.SiteTemplate
|
||||||
|
};
|
||||||
|
site = sites.AddSite(site);
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(install.HostUsername))
|
||||||
|
{
|
||||||
|
var identityUser = identityUserManager.FindByNameAsync(install.HostUsername).GetAwaiter().GetResult();
|
||||||
|
if (identityUser == null)
|
||||||
{
|
{
|
||||||
var user = new User
|
identityUser = new IdentityUser { UserName = install.HostUsername, Email = install.HostEmail, EmailConfirmed = true };
|
||||||
|
var create = identityUserManager.CreateAsync(identityUser, install.HostPassword).GetAwaiter().GetResult();
|
||||||
|
if (create.Succeeded)
|
||||||
{
|
{
|
||||||
SiteId = site.SiteId,
|
var user = new User
|
||||||
Username = install.HostUsername,
|
|
||||||
Password = install.HostPassword,
|
|
||||||
Email = install.HostEmail,
|
|
||||||
DisplayName = install.HostName,
|
|
||||||
LastIPAddress = "",
|
|
||||||
LastLoginOn = null
|
|
||||||
};
|
|
||||||
|
|
||||||
user = users.AddUser(user);
|
|
||||||
var hostRoleId = roles.GetRoles(user.SiteId, true).FirstOrDefault(item => item.Name == RoleNames.Host)?.RoleId ?? 0;
|
|
||||||
var userRole = new UserRole { UserId = user.UserId, RoleId = hostRoleId, EffectiveDate = null, ExpiryDate = null };
|
|
||||||
userRoles.AddUserRole(userRole);
|
|
||||||
|
|
||||||
// add user folder
|
|
||||||
var folder = folders.GetFolder(user.SiteId, Utilities.PathCombine("Users", Path.DirectorySeparatorChar.ToString()));
|
|
||||||
if (folder != null)
|
|
||||||
{
|
|
||||||
folders.AddFolder(new Folder
|
|
||||||
{
|
{
|
||||||
SiteId = folder.SiteId,
|
SiteId = site.SiteId,
|
||||||
ParentId = folder.FolderId,
|
Username = install.HostUsername,
|
||||||
Name = "My Folder",
|
Password = install.HostPassword,
|
||||||
Type = FolderTypes.Private,
|
Email = install.HostEmail,
|
||||||
Path = Utilities.PathCombine(folder.Path, user.UserId.ToString(), Path.DirectorySeparatorChar.ToString()),
|
DisplayName = install.HostName,
|
||||||
Order = 1,
|
LastIPAddress = "",
|
||||||
IsSystem = true,
|
LastLoginOn = null
|
||||||
Permissions = new List<Permission>
|
};
|
||||||
|
|
||||||
|
user = users.AddUser(user);
|
||||||
|
var hostRoleId = roles.GetRoles(user.SiteId, true).FirstOrDefault(item => item.Name == RoleNames.Host)?.RoleId ?? 0;
|
||||||
|
var userRole = new UserRole { UserId = user.UserId, RoleId = hostRoleId, EffectiveDate = null, ExpiryDate = null };
|
||||||
|
userRoles.AddUserRole(userRole);
|
||||||
|
|
||||||
|
// add user folder
|
||||||
|
var folder = folders.GetFolder(user.SiteId, Utilities.PathCombine("Users", Path.DirectorySeparatorChar.ToString()));
|
||||||
|
if (folder != null)
|
||||||
|
{
|
||||||
|
folders.AddFolder(new Folder
|
||||||
|
{
|
||||||
|
SiteId = folder.SiteId,
|
||||||
|
ParentId = folder.FolderId,
|
||||||
|
Name = "My Folder",
|
||||||
|
Type = FolderTypes.Private,
|
||||||
|
Path = Utilities.PathCombine(folder.Path, user.UserId.ToString(), Path.DirectorySeparatorChar.ToString()),
|
||||||
|
Order = 1,
|
||||||
|
IsSystem = true,
|
||||||
|
Permissions = new List<Permission>
|
||||||
{
|
{
|
||||||
new Permission(PermissionNames.Browse, user.UserId, true),
|
new Permission(PermissionNames.Browse, user.UserId, true),
|
||||||
new Permission(PermissionNames.View, RoleNames.Everyone, true),
|
new Permission(PermissionNames.View, RoleNames.Everyone, true),
|
||||||
new Permission(PermissionNames.Edit, user.UserId, true),
|
new Permission(PermissionNames.Edit, user.UserId, true),
|
||||||
}.EncodePermissions(),
|
}.EncodePermissions(),
|
||||||
});
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
foreach (var aliasName in install.Aliases.Split(new[] {','}, StringSplitOptions.RemoveEmptyEntries))
|
foreach (var aliasName in install.Aliases.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
|
||||||
{
|
|
||||||
alias = aliases.GetAliases().FirstOrDefault(item => item.Name == aliasName);
|
|
||||||
if (alias != null)
|
|
||||||
{
|
{
|
||||||
alias.SiteId = site.SiteId;
|
alias = aliases.GetAliases().FirstOrDefault(item => item.Name == aliasName);
|
||||||
aliases.UpdateAlias(alias);
|
if (alias != null)
|
||||||
|
{
|
||||||
|
alias.SiteId = site.SiteId;
|
||||||
|
aliases.UpdateAlias(alias);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tenant.Version = Constants.Version;
|
||||||
|
tenants.UpdateTenant(tenant);
|
||||||
|
|
||||||
|
if (site != null) log.Log(site.SiteId, Shared.LogLevel.Information, this, LogFunction.Create, "Site Created {Site}", site);
|
||||||
}
|
}
|
||||||
|
|
||||||
tenant.Version = Constants.Version;
|
|
||||||
tenants.UpdateTenant(tenant);
|
|
||||||
|
|
||||||
if (site != null) log.Log(site.SiteId, Shared.LogLevel.Information, this, LogFunction.Create, "Site Created {Site}", site);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
result.Message = "An Error Occurred Creating Site - " + ex.Message;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
result.Success = true;
|
if (string.IsNullOrEmpty(result.Message))
|
||||||
|
{
|
||||||
|
result.Success = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_filelogger.LogError(Utilities.LogMessage(this, result.Message));
|
||||||
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
|
@ -55,7 +55,7 @@ namespace Oqtane.Infrastructure
|
||||||
var filepath = Path.Combine(folder, "error.log");
|
var filepath = Path.Combine(folder, "error.log");
|
||||||
|
|
||||||
// only retain an error log for the current day as it is intended for development purposes
|
// only retain an error log for the current day as it is intended for development purposes
|
||||||
if (File.GetCreationTime(filepath).ToUniversalTime().Date < DateTime.UtcNow.Date && File.Exists(filepath))
|
if (File.Exists(filepath) && File.GetLastWriteTimeUtc(filepath).Date < DateTime.UtcNow.Date)
|
||||||
{
|
{
|
||||||
File.Delete(filepath);
|
File.Delete(filepath);
|
||||||
}
|
}
|
||||||
|
|
|
@ -68,7 +68,7 @@ namespace Oqtane.Models
|
||||||
public int Vulnerabilities { get; set; }
|
public int Vulnerabilities { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The price of the package
|
/// The price of the package ( if commercial )
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public decimal Price { get; set; }
|
public decimal Price { get; set; }
|
||||||
|
|
||||||
|
@ -81,5 +81,10 @@ namespace Oqtane.Models
|
||||||
/// The trial period in days ( if commercial )
|
/// The trial period in days ( if commercial )
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public int TrialPeriod { get; set; }
|
public int TrialPeriod { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The expiry date of the package ( if commercial )
|
||||||
|
/// </summary>
|
||||||
|
public DateTime? ExpiryDate { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user