Merge remote-tracking branch 'oqtane/dev' into dev
This commit is contained in:
commit
9d41fee2fe
|
@ -10,61 +10,106 @@
|
||||||
<TabStrip>
|
<TabStrip>
|
||||||
<TabPanel Name="Download" ResourceKey="Download">
|
<TabPanel Name="Download" ResourceKey="Download">
|
||||||
<div class="row justify-content-center mb-3">
|
<div class="row justify-content-center mb-3">
|
||||||
<div class="col-sm-6">
|
<div class="text-center">
|
||||||
|
<div class="form-check form-check-inline">
|
||||||
|
<input id="free" class="form-check-input" type="radio" checked="@(_price == "free")" name="Price" @onchange="@(() => PriceChanged("free"))" />
|
||||||
|
<label class="form-check-label" for="free">@SharedLocalizer["Free"]</label>
|
||||||
|
</div>
|
||||||
|
<div class="form-check form-check-inline">
|
||||||
|
<input id="paid" class="form-check-input" type="radio" checked="@(_price == "paid")" name="Price" @onchange="@(() => PriceChanged("paid"))" />
|
||||||
|
<label class="form-check-label" for="paid">@SharedLocalizer["Paid"]</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row justify-content-center mb-3">
|
||||||
|
<div class="col">
|
||||||
<div class="input-group">
|
<div class="input-group">
|
||||||
<select id="price" class="form-select custom-select" @onchange="(e => PriceChanged(e))">
|
<span class="input-group-text">Product</span>
|
||||||
<option value="free">@SharedLocalizer["Free"]</option>
|
|
||||||
<option value="paid">@SharedLocalizer["Paid"]</option>
|
|
||||||
</select>
|
|
||||||
<input id="search" class="form-control" placeholder="@SharedLocalizer["Search.Hint"]" @bind="@_search" />
|
<input id="search" class="form-control" placeholder="@SharedLocalizer["Search.Hint"]" @bind="@_search" />
|
||||||
<button type="button" class="btn btn-primary" @onclick="Search">@SharedLocalizer["Search"]</button>
|
<button type="button" class="btn btn-primary" @onclick="Search">@SharedLocalizer["Search"]</button>
|
||||||
<button type="button" class="btn btn-secondary" @onclick="Reset">@SharedLocalizer["Reset"]</button>
|
<button type="button" class="btn btn-secondary" @onclick="Reset">@SharedLocalizer["Reset"]</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="row mb-3">
|
||||||
@if (_packages != null)
|
<div class="col">
|
||||||
|
@if (_initialized)
|
||||||
{
|
{
|
||||||
if (_packages.Count > 0)
|
<br />
|
||||||
|
<div class="row mb-3">
|
||||||
|
<div class="col-sm-4">
|
||||||
|
<h3>@((_packages != null) ? _packages.Count : 0) @SharedLocalizer["Search.Results"]</h3>
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-4">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-4">
|
||||||
|
<select class="form-select" value="@_sort" @onchange="(e => SortChanged(e))">
|
||||||
|
<option value="popularity">@SharedLocalizer["Search.Popularity"]</option>
|
||||||
|
<option value="alphabetical">@SharedLocalizer["Search.Alphabetical"]</option>
|
||||||
|
<option value="downloads">@SharedLocalizer["Search.Downloads"]</option>
|
||||||
|
<option value="recent">@SharedLocalizer["Search.RecentlyReleased"]</option>
|
||||||
|
@if (_price == "paid")
|
||||||
{
|
{
|
||||||
<Pager Items="@_packages">
|
<option value="price">@SharedLocalizer["Search.Price"]</option>
|
||||||
<Row>
|
|
||||||
<td>
|
|
||||||
<h3 style="display: inline;"><a href="@context.ProductUrl" target="_new">@context.Name</a></h3> by: <strong><a href="@context.OwnerUrl" target="new">@context.Owner</a></strong><br />
|
|
||||||
@(context.Description.Length > 400 ? (context.Description.Substring(0, 400) + "...") : context.Description)<br />
|
|
||||||
<strong>@(String.Format("{0:n0}", context.Downloads))</strong> @SharedLocalizer["Search.Downloads"] |
|
|
||||||
@SharedLocalizer["Search.Released"]: <strong>@context.ReleaseDate.ToString("MMM dd, yyyy")</strong> |
|
|
||||||
@SharedLocalizer["Search.Version"]: <strong>@context.Version</strong>
|
|
||||||
@((MarkupString)(!string.IsNullOrEmpty(context.PackageUrl) ? " | " + SharedLocalizer["Search.Source"] + ": <strong>" + new Uri(context.PackageUrl).Host + "</strong>" : ""))
|
|
||||||
@((MarkupString)(context.TrialPeriod > 0 ? " | <strong>" + context.TrialPeriod + " " + @SharedLocalizer["Trial"] + "</strong>" : ""))
|
|
||||||
</td>
|
|
||||||
<td style="width: 1px; vertical-align: middle;">
|
|
||||||
@if (context.Price != null && !string.IsNullOrEmpty(context.PackageUrl))
|
|
||||||
{
|
|
||||||
<button type="button" class="btn btn-primary" @onclick=@(async () => await GetPackage(context.PackageId, context.Version))>@SharedLocalizer["Download"]</button>
|
|
||||||
}
|
}
|
||||||
</td>
|
</select>
|
||||||
<td style="width: 1px; vertical-align: middle;">
|
</div>
|
||||||
@if (context.Price != null && !string.IsNullOrEmpty(context.PaymentUrl))
|
</div>
|
||||||
|
<Pager Format="Grid" Items="@_packages" DisplayPages="1" PageSize="9" Toolbar="Both" Class="container-fluid px-0" RowClass="row g-0" ColumnClass="col-lg-4 col-md-6">
|
||||||
|
<Row>
|
||||||
|
<div class="m-2 p-2 d-flex justify-content-center">
|
||||||
|
<div class="container-fluid px-0">
|
||||||
|
<div class="row g-0">
|
||||||
|
<div class="col-6">
|
||||||
|
@if (context.LogoFileId != null)
|
||||||
{
|
{
|
||||||
<a class="btn btn-primary" style="text-decoration: none !important" href="@context.PaymentUrl" target="_new">@context.Price.Value.ToString("$#,##0.00")</a>
|
<img src="@GetLogo(context.LogoFileId.Value)" class="img-fluid" alt="@context.Name" />
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
<img src="/package.png" class="img-fluid" alt="@context.Name" />
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
<div class="col-6 text-end">
|
||||||
|
<small>@SharedLocalizer["Search.Version"]:</small> <strong>@context.Version</strong>
|
||||||
|
<br /><small>@SharedLocalizer["Search.Downloads"]:</small> <strong>@(String.Format("{0:n0}", context.Downloads))</strong>
|
||||||
|
<br /><small>@SharedLocalizer["Search.Released"]:</small> <strong>@context.ReleaseDate.ToString("MM/dd/yyyy")</strong>
|
||||||
|
@if (!string.IsNullOrEmpty(context.PackageUrl))
|
||||||
|
{
|
||||||
|
<br /><small>@SharedLocalizer["Search.Source"]:</small> <strong>@(new Uri(context.PackageUrl).Host)</strong>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row g-0">
|
||||||
|
<div class="col">
|
||||||
|
<h3 style="display: inline;"><a href="@context.ProductUrl" target="_blank">@context.Name</a></h3><br />
|
||||||
|
<small>@SharedLocalizer["Search.By"]:</small> <strong><a href="@context.OwnerUrl" target="new">@context.Owner</a></strong><br />
|
||||||
|
@(context.Description.Length > 400 ? (context.Description.Substring(0, 400) + "...") : context.Description)<br />
|
||||||
|
@if (context.Price != null && !string.IsNullOrEmpty(context.PaymentUrl))
|
||||||
|
{
|
||||||
|
<small>@SharedLocalizer["Search.Price"]:</small> <strong>@context.Price.Value.ToString("$#,##0.00")</strong>
|
||||||
|
@((MarkupString)(context.TrialPeriod > 0 ? " <strong>(" + context.TrialPeriod + " Day Trial)</strong>" : ""))
|
||||||
|
}
|
||||||
|
<br />
|
||||||
|
@if (!string.IsNullOrEmpty(context.PackageUrl))
|
||||||
{
|
{
|
||||||
<button type="button" class="btn btn-primary" @onclick=@(async () => await GetPackage(context.PackageId, context.Version))>@SharedLocalizer["Download"]</button>
|
<button type="button" class="btn btn-primary" @onclick=@(async () => await GetPackage(context.PackageId, context.Version))>@SharedLocalizer["Download"]</button>
|
||||||
}
|
}
|
||||||
</td>
|
@if (context.Price != null && !string.IsNullOrEmpty(context.PaymentUrl))
|
||||||
|
{
|
||||||
|
<a class="btn btn-success ms-2" style="text-decoration: none !important" href="@context.PaymentUrl" target="_new">@SharedLocalizer["Buy"]</a>
|
||||||
|
}
|
||||||
|
<br />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</Row>
|
</Row>
|
||||||
</Pager>
|
</Pager>
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
<br />
|
|
||||||
<div class="mx-auto text-center">
|
|
||||||
@Localizer["Search.NoResults"]
|
|
||||||
</div>
|
</div>
|
||||||
}
|
</div>
|
||||||
}
|
|
||||||
<br />
|
<br />
|
||||||
<ModuleMessage Type="MessageType.Info" Message="@SharedLocalizer["Oqtane.Marketplace"]" />
|
<ModuleMessage Type="MessageType.Info" Message="@SharedLocalizer["Oqtane.Marketplace"]" />
|
||||||
</TabPanel>
|
</TabPanel>
|
||||||
|
@ -116,8 +161,10 @@
|
||||||
<NavLink class="btn btn-secondary" href="@NavigateUrl()">@SharedLocalizer["Cancel"]</NavLink>
|
<NavLink class="btn btn-secondary" href="@NavigateUrl()">@SharedLocalizer["Cancel"]</NavLink>
|
||||||
|
|
||||||
@code {
|
@code {
|
||||||
|
private bool _initialized = false;
|
||||||
private List<Package> _packages;
|
private List<Package> _packages;
|
||||||
private string _price = "free";
|
private string _price = "free";
|
||||||
|
private string _sort = "popularity";
|
||||||
private string _search = "";
|
private string _search = "";
|
||||||
private string _productname = "";
|
private string _productname = "";
|
||||||
private string _packageid = "";
|
private string _packageid = "";
|
||||||
|
@ -131,6 +178,7 @@
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
await LoadModuleDefinitions();
|
await LoadModuleDefinitions();
|
||||||
|
_initialized = true;
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
@ -141,8 +189,10 @@
|
||||||
|
|
||||||
private async Task LoadModuleDefinitions()
|
private async Task LoadModuleDefinitions()
|
||||||
{
|
{
|
||||||
|
ShowProgressIndicator();
|
||||||
|
|
||||||
var moduledefinitions = await ModuleDefinitionService.GetModuleDefinitionsAsync(PageState.Site.SiteId);
|
var moduledefinitions = await ModuleDefinitionService.GetModuleDefinitionsAsync(PageState.Site.SiteId);
|
||||||
_packages = await PackageService.GetPackagesAsync("module", _search, _price, "");
|
_packages = await PackageService.GetPackagesAsync("module", _search, _price, "", _sort);
|
||||||
|
|
||||||
if (_packages != null)
|
if (_packages != null)
|
||||||
{
|
{
|
||||||
|
@ -154,22 +204,23 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
HideProgressIndicator();
|
||||||
}
|
}
|
||||||
|
|
||||||
private async void PriceChanged(ChangeEventArgs e)
|
private string GetLogo(int fileid)
|
||||||
{
|
{
|
||||||
try
|
var url = ImageUrl(fileid, 100, 100);
|
||||||
|
url = (!string.IsNullOrEmpty(PageState.Alias.Path)) ? url.Substring(PageState.Alias.Path.Length + 1) : url;
|
||||||
|
return Constants.PackageRegistryUrl + url;
|
||||||
|
}
|
||||||
|
|
||||||
|
private async void PriceChanged(string price)
|
||||||
{
|
{
|
||||||
_price = (string)e.Value;
|
_price = price;
|
||||||
_search = "";
|
|
||||||
await LoadModuleDefinitions();
|
await LoadModuleDefinitions();
|
||||||
StateHasChanged();
|
StateHasChanged();
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
await logger.LogError(ex, "Error On PriceChanged");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task Search()
|
private async Task Search()
|
||||||
{
|
{
|
||||||
|
@ -196,6 +247,12 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async void SortChanged(ChangeEventArgs e)
|
||||||
|
{
|
||||||
|
_sort = (string)e.Value;
|
||||||
|
await LoadModuleDefinitions();
|
||||||
|
}
|
||||||
|
|
||||||
private void HideModal()
|
private void HideModal()
|
||||||
{
|
{
|
||||||
_productname = "";
|
_productname = "";
|
||||||
|
|
|
@ -10,61 +10,108 @@
|
||||||
<TabStrip>
|
<TabStrip>
|
||||||
<TabPanel Name="Download" ResourceKey="Download">
|
<TabPanel Name="Download" ResourceKey="Download">
|
||||||
<div class="row justify-content-center mb-3">
|
<div class="row justify-content-center mb-3">
|
||||||
<div class="col-sm-6">
|
<div class="text-center">
|
||||||
|
<div class="form-check form-check-inline">
|
||||||
|
<input id="free" class="form-check-input" type="radio" checked="@(_price == "free")" name="Price" @onchange="@(() => PriceChanged("free"))" />
|
||||||
|
<label class="form-check-label" for="free">@SharedLocalizer["Free"]</label>
|
||||||
|
</div>
|
||||||
|
<div class="form-check form-check-inline">
|
||||||
|
<input id="paid" class="form-check-input" type="radio" checked="@(_price == "paid")" name="Price" @onchange="@(() => PriceChanged("paid"))" />
|
||||||
|
<label class="form-check-label" for="paid">@SharedLocalizer["Paid"]</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row justify-content-center mb-3">
|
||||||
|
<div class="col">
|
||||||
<div class="input-group">
|
<div class="input-group">
|
||||||
<select id="price" class="form-select custom-select" @onchange="(e => PriceChanged(e))">
|
<span class="input-group-text">Product</span>
|
||||||
<option value="free">@SharedLocalizer["Free"]</option>
|
|
||||||
<option value="paid">@SharedLocalizer["Paid"]</option>
|
|
||||||
</select>
|
|
||||||
<input id="search" class="form-control" placeholder="@SharedLocalizer["Search.Hint"]" @bind="@_search" />
|
<input id="search" class="form-control" placeholder="@SharedLocalizer["Search.Hint"]" @bind="@_search" />
|
||||||
<button type="button" class="btn btn-primary" @onclick="Search">@SharedLocalizer["Search"]</button>
|
<button type="button" class="btn btn-primary" @onclick="Search">@SharedLocalizer["Search"]</button>
|
||||||
<button type="button" class="btn btn-secondary" @onclick="Reset">@SharedLocalizer["Reset"]</button>
|
<button type="button" class="btn btn-secondary" @onclick="Reset">@SharedLocalizer["Reset"]</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="row mb-3">
|
||||||
@if (_packages != null)
|
<div class="col">
|
||||||
|
@if (_initialized)
|
||||||
{
|
{
|
||||||
if (_packages.Count > 0)
|
<br />
|
||||||
|
<div class="row mb-3">
|
||||||
|
<div class="col-sm-4">
|
||||||
|
<h3>@((_packages != null) ? _packages.Count : 0) @SharedLocalizer["Search.Results"]</h3>
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-4">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-4">
|
||||||
|
<select class="form-select" value="@_sort" @onchange="(e => SortChanged(e))">
|
||||||
|
<option value="popularity">@SharedLocalizer["Search.Popularity"]</option>
|
||||||
|
<option value="alphabetical">@SharedLocalizer["Search.Alphabetical"]</option>
|
||||||
|
<option value="downloads">@SharedLocalizer["Search.Downloads"]</option>
|
||||||
|
<option value="recent">@SharedLocalizer["Search.RecentlyReleased"]</option>
|
||||||
|
@if (_price == "paid")
|
||||||
{
|
{
|
||||||
<Pager Items="@_packages">
|
<option value="price">@SharedLocalizer["Search.Price"]</option>
|
||||||
<Row>
|
|
||||||
<td>
|
|
||||||
<h3 style="display: inline;"><a href="@context.ProductUrl" target="_new">@context.Name</a></h3> @SharedLocalizer["Search.By"]: <strong><a href="@context.OwnerUrl" target="new">@context.Owner</a></strong><br />
|
|
||||||
@(context.Description.Length > 400 ? (context.Description.Substring(0, 400) + "...") : context.Description)<br />
|
|
||||||
<strong>@(String.Format("{0:n0}", context.Downloads))</strong> @SharedLocalizer["Search.Downloads"] |
|
|
||||||
@SharedLocalizer["Search.Released"]: <strong>@context.ReleaseDate.ToString("MMM dd, yyyy")</strong> |
|
|
||||||
@SharedLocalizer["Search.Version"]: <strong>@context.Version</strong>
|
|
||||||
@((MarkupString)(!string.IsNullOrEmpty(context.PackageUrl) ? " | " + SharedLocalizer["Search.Source"] + ": <strong>" + new Uri(context.PackageUrl).Host + "</strong>" : ""))
|
|
||||||
@((MarkupString)(context.TrialPeriod > 0 ? " | <strong>" + context.TrialPeriod + " " + @SharedLocalizer["Trial"] + "</strong>" : ""))
|
|
||||||
</td>
|
|
||||||
<td style="width: 1px; vertical-align: middle;">
|
|
||||||
@if (context.Price != null && !string.IsNullOrEmpty(context.PackageUrl))
|
|
||||||
{
|
|
||||||
<button type="button" class="btn btn-primary" @onclick=@(async () => await GetPackage(context.PackageId, context.Version))>@SharedLocalizer["Download"]</button>
|
|
||||||
}
|
}
|
||||||
</td>
|
</select>
|
||||||
<td style="width: 1px; vertical-align: middle;">
|
</div>
|
||||||
@if (context.Price != null && !string.IsNullOrEmpty(context.PaymentUrl))
|
</div>
|
||||||
|
<Pager Format="Grid" Items="@_packages" DisplayPages="1" PageSize="9" Toolbar="Both" Class="container-fluid px-0" RowClass="row g-0" ColumnClass="col-lg-4 col-md-6">
|
||||||
|
<Row>
|
||||||
|
<div class="m-2 p-2 d-flex justify-content-center">
|
||||||
|
<div class="container-fluid px-0">
|
||||||
|
<div class="row g-0">
|
||||||
|
<div class="col-6">
|
||||||
|
@if (context.LogoFileId != null)
|
||||||
{
|
{
|
||||||
<a class="btn btn-primary" style="text-decoration: none !important" href="@context.PaymentUrl" target="_new">@context.Price.Value.ToString("$#,##0.00")</a>
|
<img src="@GetLogo(context.LogoFileId.Value)" class="img-fluid" alt="@context.Name" />
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
<img src="/package.png" class="img-fluid" alt="@context.Name" />
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
<div class="col-6 text-end">
|
||||||
|
<small>@SharedLocalizer["Search.Version"]:</small> <strong>@context.Version</strong>
|
||||||
|
<br /><small>@SharedLocalizer["Search.Downloads"]:</small> <strong>@(String.Format("{0:n0}", context.Downloads))</strong>
|
||||||
|
<br /><small>@SharedLocalizer["Search.Released"]:</small> <strong>@context.ReleaseDate.ToString("MM/dd/yyyy")</strong>
|
||||||
|
@if (!string.IsNullOrEmpty(context.PackageUrl))
|
||||||
|
{
|
||||||
|
<br />
|
||||||
|
|
||||||
|
<small>@SharedLocalizer["Search.Source"]:</small> <strong>@(new Uri(context.PackageUrl).Host)</strong>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row g-0">
|
||||||
|
<div class="col">
|
||||||
|
<h3 style="display: inline;"><a href="@context.ProductUrl" target="_blank">@context.Name</a></h3><br />
|
||||||
|
<small>@SharedLocalizer["Search.By"]:</small> <strong><a href="@context.OwnerUrl" target="new">@context.Owner</a></strong><br />
|
||||||
|
@(context.Description.Length > 400 ? (context.Description.Substring(0, 400) + "...") : context.Description)<br />
|
||||||
|
@if (context.Price != null && !string.IsNullOrEmpty(context.PaymentUrl))
|
||||||
|
{
|
||||||
|
<small>@SharedLocalizer["Search.Price"]:</small> <strong>@context.Price.Value.ToString("$#,##0.00")</strong>
|
||||||
|
@((MarkupString)(context.TrialPeriod > 0 ? " <strong>(" + context.TrialPeriod + " Day Trial)</strong>" : ""))
|
||||||
|
}
|
||||||
|
<br />
|
||||||
|
@if (!string.IsNullOrEmpty(context.PackageUrl))
|
||||||
{
|
{
|
||||||
<button type="button" class="btn btn-primary" @onclick=@(async () => await GetPackage(context.PackageId, context.Version))>@SharedLocalizer["Download"]</button>
|
<button type="button" class="btn btn-primary" @onclick=@(async () => await GetPackage(context.PackageId, context.Version))>@SharedLocalizer["Download"]</button>
|
||||||
}
|
}
|
||||||
</td>
|
@if (context.Price != null && !string.IsNullOrEmpty(context.PaymentUrl))
|
||||||
|
{
|
||||||
|
<a class="btn btn-success ms-2" style="text-decoration: none !important" href="@context.PaymentUrl" target="_new">@SharedLocalizer["Buy"]</a>
|
||||||
|
}
|
||||||
|
<br />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</Row>
|
</Row>
|
||||||
</Pager>
|
</Pager>
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
<br />
|
|
||||||
<div class="mx-auto text-center">
|
|
||||||
@Localizer["Search.NoResults"]
|
|
||||||
</div>
|
</div>
|
||||||
}
|
</div>
|
||||||
}
|
|
||||||
<br />
|
<br />
|
||||||
<ModuleMessage Type="MessageType.Info" Message="@SharedLocalizer["Oqtane.Marketplace"]" />
|
<ModuleMessage Type="MessageType.Info" Message="@SharedLocalizer["Oqtane.Marketplace"]" />
|
||||||
</TabPanel>
|
</TabPanel>
|
||||||
|
@ -116,8 +163,10 @@
|
||||||
<NavLink class="btn btn-secondary" href="@NavigateUrl()">@SharedLocalizer["Cancel"]</NavLink>
|
<NavLink class="btn btn-secondary" href="@NavigateUrl()">@SharedLocalizer["Cancel"]</NavLink>
|
||||||
|
|
||||||
@code {
|
@code {
|
||||||
|
private bool _initialized = false;
|
||||||
private List<Package> _packages;
|
private List<Package> _packages;
|
||||||
private string _price = "free";
|
private string _price = "free";
|
||||||
|
private string _sort = "popularity";
|
||||||
private string _search = "";
|
private string _search = "";
|
||||||
private string _productname = "";
|
private string _productname = "";
|
||||||
private string _license = "";
|
private string _license = "";
|
||||||
|
@ -131,6 +180,7 @@
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
await LoadThemes();
|
await LoadThemes();
|
||||||
|
_initialized = true;
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
@ -141,8 +191,10 @@
|
||||||
|
|
||||||
private async Task LoadThemes()
|
private async Task LoadThemes()
|
||||||
{
|
{
|
||||||
|
ShowProgressIndicator();
|
||||||
|
|
||||||
var themes = await ThemeService.GetThemesAsync();
|
var themes = await ThemeService.GetThemesAsync();
|
||||||
_packages = await PackageService.GetPackagesAsync("theme", _search, _price, "");
|
_packages = await PackageService.GetPackagesAsync("theme", _search, _price, "", _sort);
|
||||||
|
|
||||||
if (_packages != null)
|
if (_packages != null)
|
||||||
{
|
{
|
||||||
|
@ -154,22 +206,23 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
HideProgressIndicator();
|
||||||
}
|
}
|
||||||
|
|
||||||
private async void PriceChanged(ChangeEventArgs e)
|
private string GetLogo(int fileid)
|
||||||
{
|
{
|
||||||
try
|
var url = ImageUrl(fileid, 100, 100);
|
||||||
|
url = (!string.IsNullOrEmpty(PageState.Alias.Path)) ? url.Substring(PageState.Alias.Path.Length + 1) : url;
|
||||||
|
return Constants.PackageRegistryUrl + url;
|
||||||
|
}
|
||||||
|
|
||||||
|
private async void PriceChanged(string price)
|
||||||
{
|
{
|
||||||
_price = (string)e.Value;
|
_price = price;
|
||||||
_search = "";
|
|
||||||
await LoadThemes();
|
await LoadThemes();
|
||||||
StateHasChanged();
|
StateHasChanged();
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
await logger.LogError(ex, "Error On PriceChanged");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task Search()
|
private async Task Search()
|
||||||
{
|
{
|
||||||
|
@ -196,6 +249,12 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async void SortChanged(ChangeEventArgs e)
|
||||||
|
{
|
||||||
|
_sort = (string)e.Value;
|
||||||
|
await LoadThemes();
|
||||||
|
}
|
||||||
|
|
||||||
private void HideModal()
|
private void HideModal()
|
||||||
{
|
{
|
||||||
_productname = "";
|
_productname = "";
|
||||||
|
|
|
@ -136,7 +136,7 @@
|
||||||
<value>No Modules Match The Criteria Provided Or Package Service Is Disabled</value>
|
<value>No Modules Match The Criteria Provided Or Package Service Is Disabled</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Download.Heading" xml:space="preserve">
|
<data name="Download.Heading" xml:space="preserve">
|
||||||
<value>Download</value>
|
<value>Marketplace</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Upload.Heading" xml:space="preserve">
|
<data name="Upload.Heading" xml:space="preserve">
|
||||||
<value>Upload</value>
|
<value>Upload</value>
|
||||||
|
|
|
@ -135,4 +135,10 @@
|
||||||
<data name="Search.NoResults" xml:space="preserve">
|
<data name="Search.NoResults" xml:space="preserve">
|
||||||
<value>No Themes Match The Criteria Provided Or Package Service Is Disabled</value>
|
<value>No Themes Match The Criteria Provided Or Package Service Is Disabled</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="Download.Heading" xml:space="preserve">
|
||||||
|
<value>Marketplace</value>
|
||||||
|
</data>
|
||||||
|
<data name="Upload.Heading" xml:space="preserve">
|
||||||
|
<value>Upload</value>
|
||||||
|
</data>
|
||||||
</root>
|
</root>
|
|
@ -223,13 +223,13 @@
|
||||||
<value>by</value>
|
<value>by</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Search.Downloads" xml:space="preserve">
|
<data name="Search.Downloads" xml:space="preserve">
|
||||||
<value>downloads</value>
|
<value>Downloads</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Search.Released" xml:space="preserve">
|
<data name="Search.Released" xml:space="preserve">
|
||||||
<value>released</value>
|
<value>Released</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Search.Version" xml:space="preserve">
|
<data name="Search.Version" xml:space="preserve">
|
||||||
<value>version</value>
|
<value>Version</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Edit" xml:space="preserve">
|
<data name="Edit" xml:space="preserve">
|
||||||
<value>Edit</value>
|
<value>Edit</value>
|
||||||
|
@ -277,19 +277,19 @@
|
||||||
<value>Installed Version</value>
|
<value>Installed Version</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Search.Source" xml:space="preserve">
|
<data name="Search.Source" xml:space="preserve">
|
||||||
<value>source</value>
|
<value>Source</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Message.InfoRequired" xml:space="preserve">
|
<data name="Message.InfoRequired" xml:space="preserve">
|
||||||
<value>Please Provide All Required Information</value>
|
<value>Please Provide All Required Information</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Free" xml:space="preserve">
|
<data name="Free" xml:space="preserve">
|
||||||
<value>Free</value>
|
<value>Open Source</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Paid" xml:space="preserve">
|
<data name="Paid" xml:space="preserve">
|
||||||
<value>Paid</value>
|
<value>Commercial</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Search.Price" xml:space="preserve">
|
<data name="Search.Price" xml:space="preserve">
|
||||||
<value>price</value>
|
<value>Price</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Accept" xml:space="preserve">
|
<data name="Accept" xml:space="preserve">
|
||||||
<value>Accept</value>
|
<value>Accept</value>
|
||||||
|
@ -390,4 +390,16 @@
|
||||||
<data name="Support" xml:space="preserve">
|
<data name="Support" xml:space="preserve">
|
||||||
<value>Support</value>
|
<value>Support</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="Search.Alphabetical" xml:space="preserve">
|
||||||
|
<value>Alphabetical</value>
|
||||||
|
</data>
|
||||||
|
<data name="Buy" xml:space="preserve">
|
||||||
|
<value>Buy Now</value>
|
||||||
|
</data>
|
||||||
|
<data name="Search.Popularity" xml:space="preserve">
|
||||||
|
<value>Popularity</value>
|
||||||
|
</data>
|
||||||
|
<data name="Search.Results" xml:space="preserve">
|
||||||
|
<value>Results</value>
|
||||||
|
</data>
|
||||||
</root>
|
</root>
|
|
@ -22,7 +22,7 @@ namespace Oqtane.Services
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public async Task<List<Alias>> GetAliasesAsync()
|
public async Task<List<Alias>> GetAliasesAsync()
|
||||||
{
|
{
|
||||||
List<Alias> aliases = await GetJsonAsync<List<Alias>>(ApiUrl);
|
List<Alias> aliases = await GetJsonAsync<List<Alias>>(ApiUrl, Enumerable.Empty<Alias>().ToList());
|
||||||
return aliases.OrderBy(item => item.Name).ToList();
|
return aliases.OrderBy(item => item.Name).ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -145,10 +145,19 @@ namespace Oqtane.Services
|
||||||
{
|
{
|
||||||
return await response.Content.ReadFromJsonAsync<T>();
|
return await response.Content.ReadFromJsonAsync<T>();
|
||||||
}
|
}
|
||||||
|
|
||||||
return default;
|
return default;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected async Task<T> GetJsonAsync<T>(string uri, T defaultResult)
|
||||||
|
{
|
||||||
|
var response = await GetHttpClient().GetAsync(uri, HttpCompletionOption.ResponseHeadersRead, CancellationToken.None);
|
||||||
|
if (await CheckResponse(response, uri) && ValidateJsonContent(response.Content))
|
||||||
|
{
|
||||||
|
return await response.Content.ReadFromJsonAsync<T>();
|
||||||
|
}
|
||||||
|
return defaultResult;
|
||||||
|
}
|
||||||
|
|
||||||
protected async Task PutAsync(string uri)
|
protected async Task PutAsync(string uri)
|
||||||
{
|
{
|
||||||
var response = await GetHttpClient().PutAsync(uri, null);
|
var response = await GetHttpClient().PutAsync(uri, null);
|
||||||
|
|
|
@ -70,7 +70,7 @@
|
||||||
var elements = (">" + content.Replace("\n", "") + "<").Split("><");
|
var elements = (">" + content.Replace("\n", "") + "<").Split("><");
|
||||||
foreach (var element in elements)
|
foreach (var element in elements)
|
||||||
{
|
{
|
||||||
if (!string.IsNullOrEmpty(element) && !element.Contains("script"))
|
if (!string.IsNullOrEmpty(element) && !element.ToLower().StartsWith("script"))
|
||||||
{
|
{
|
||||||
if (!headcontent.Contains("<" + element + ">"))
|
if (!headcontent.Contains("<" + element + ">"))
|
||||||
{
|
{
|
||||||
|
|
|
@ -14,7 +14,7 @@ dotnet publish ..\Oqtane.Server\Oqtane.Server.csproj /p:Configuration=Release
|
||||||
del /F/Q/S "..\Oqtane.Server\bin\Release\net7.0\publish\wwwroot\Content" > NUL
|
del /F/Q/S "..\Oqtane.Server\bin\Release\net7.0\publish\wwwroot\Content" > NUL
|
||||||
rmdir /Q/S "..\Oqtane.Server\bin\Release\net7.0\publish\wwwroot\Content"
|
rmdir /Q/S "..\Oqtane.Server\bin\Release\net7.0\publish\wwwroot\Content"
|
||||||
setlocal ENABLEDELAYEDEXPANSION
|
setlocal ENABLEDELAYEDEXPANSION
|
||||||
set retain=Oqtane.Modules.Admin.Login,Oqtane.Modules.HtmlText,Templates
|
set retain=Oqtane.Modules.Admin.Login,Oqtane.Modules.HtmlText
|
||||||
for /D %%i in ("..\Oqtane.Server\bin\Release\net7.0\publish\wwwroot\Modules\*") do (
|
for /D %%i in ("..\Oqtane.Server\bin\Release\net7.0\publish\wwwroot\Modules\*") do (
|
||||||
set /A found=0
|
set /A found=0
|
||||||
for %%j in (%retain%) do (
|
for %%j in (%retain%) do (
|
||||||
|
@ -22,7 +22,7 @@ if "%%~nxi" == "%%j" set /A found=1
|
||||||
)
|
)
|
||||||
if not !found! == 1 rmdir /Q/S "%%i"
|
if not !found! == 1 rmdir /Q/S "%%i"
|
||||||
)
|
)
|
||||||
set retain=Oqtane.Themes.BlazorTheme,Oqtane.Themes.OqtaneTheme,Templates
|
set retain=Oqtane.Themes.BlazorTheme,Oqtane.Themes.OqtaneTheme
|
||||||
for /D %%i in ("..\Oqtane.Server\bin\Release\net7.0\publish\wwwroot\Themes\*") do (
|
for /D %%i in ("..\Oqtane.Server\bin\Release\net7.0\publish\wwwroot\Themes\*") do (
|
||||||
set /A found=0
|
set /A found=0
|
||||||
for %%j in (%retain%) do (
|
for %%j in (%retain%) do (
|
||||||
|
|
|
@ -572,7 +572,7 @@ namespace Oqtane.Controllers
|
||||||
// validation
|
// validation
|
||||||
if (!Enum.TryParse(mode, true, out ResizeMode _)) mode = "crop";
|
if (!Enum.TryParse(mode, true, out ResizeMode _)) mode = "crop";
|
||||||
if (!Enum.TryParse(position, true, out AnchorPositionMode _)) position = "center";
|
if (!Enum.TryParse(position, true, out AnchorPositionMode _)) position = "center";
|
||||||
if (!Color.TryParseHex("#" + background, out _)) background = "000000";
|
if (!Color.TryParseHex("#" + background, out _)) background = "transparent";
|
||||||
if (!int.TryParse(rotate, out _)) rotate = "0";
|
if (!int.TryParse(rotate, out _)) rotate = "0";
|
||||||
rotate = (int.Parse(rotate) < 0 || int.Parse(rotate) > 360) ? "0" : rotate;
|
rotate = (int.Parse(rotate) < 0 || int.Parse(rotate) > 360) ? "0" : rotate;
|
||||||
if (!bool.TryParse(recreate, out _)) recreate = "false";
|
if (!bool.TryParse(recreate, out _)) recreate = "false";
|
||||||
|
@ -644,10 +644,23 @@ namespace Oqtane.Controllers
|
||||||
Mode = resizemode,
|
Mode = resizemode,
|
||||||
Position = anchorpositionmode,
|
Position = anchorpositionmode,
|
||||||
Size = new Size(width, height)
|
Size = new Size(width, height)
|
||||||
})
|
}));
|
||||||
.BackgroundColor(Color.ParseHex("#" + background)));
|
|
||||||
|
|
||||||
image.Save(imagepath, new PngEncoder());
|
if (background != "transparent")
|
||||||
|
{
|
||||||
|
image.Mutate(x => x
|
||||||
|
.BackgroundColor(Color.ParseHex("#" + background)));
|
||||||
|
}
|
||||||
|
|
||||||
|
PngEncoder encoder = new PngEncoder
|
||||||
|
{
|
||||||
|
ColorType = PngColorType.RgbWithAlpha,
|
||||||
|
TransparentColorMode = PngTransparentColorMode.Preserve,
|
||||||
|
BitDepth = PngBitDepth.Bit8,
|
||||||
|
CompressionLevel = PngCompressionLevel.BestSpeed
|
||||||
|
};
|
||||||
|
|
||||||
|
image.Save(imagepath, encoder);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -676,9 +689,16 @@ namespace Oqtane.Controllers
|
||||||
{
|
{
|
||||||
path = Utilities.PathCombine(path, folder, Path.DirectorySeparatorChar.ToString());
|
path = Utilities.PathCombine(path, folder, Path.DirectorySeparatorChar.ToString());
|
||||||
if (!Directory.Exists(path))
|
if (!Directory.Exists(path))
|
||||||
|
{
|
||||||
|
try
|
||||||
{
|
{
|
||||||
Directory.CreateDirectory(path);
|
Directory.CreateDirectory(path);
|
||||||
}
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.Log(LogLevel.Error, this, LogFunction.Create, ex, "Unable To Create Folder {Folder}", path);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -88,6 +88,7 @@ namespace Oqtane.Controllers
|
||||||
public Folder GetByPath(int siteId, string path)
|
public Folder GetByPath(int siteId, string path)
|
||||||
{
|
{
|
||||||
var folderPath = WebUtility.UrlDecode(path).Replace("\\", "/");
|
var folderPath = WebUtility.UrlDecode(path).Replace("\\", "/");
|
||||||
|
folderPath = (folderPath == "/") ? "" : folderPath;
|
||||||
if (!folderPath.EndsWith("/") && folderPath != "")
|
if (!folderPath.EndsWith("/") && folderPath != "")
|
||||||
{
|
{
|
||||||
folderPath += "/";
|
folderPath += "/";
|
||||||
|
|
|
@ -283,6 +283,8 @@ namespace Oqtane.Controllers
|
||||||
var templates = new List<Template>();
|
var templates = new List<Template>();
|
||||||
var root = Directory.GetParent(_environment.ContentRootPath);
|
var root = Directory.GetParent(_environment.ContentRootPath);
|
||||||
string templatePath = Utilities.PathCombine(_environment.WebRootPath, "Modules", "Templates", Path.DirectorySeparatorChar.ToString());
|
string templatePath = Utilities.PathCombine(_environment.WebRootPath, "Modules", "Templates", Path.DirectorySeparatorChar.ToString());
|
||||||
|
if (Directory.Exists(templatePath))
|
||||||
|
{
|
||||||
foreach (string directory in Directory.GetDirectories(templatePath))
|
foreach (string directory in Directory.GetDirectories(templatePath))
|
||||||
{
|
{
|
||||||
string name = directory.Replace(templatePath, "");
|
string name = directory.Replace(templatePath, "");
|
||||||
|
@ -302,6 +304,7 @@ namespace Oqtane.Controllers
|
||||||
templates.Add(new Template { Name = name, Title = name, Type = "External", Version = "", Location = Utilities.PathCombine(root.Parent.ToString(), Path.DirectorySeparatorChar.ToString()) });
|
templates.Add(new Template { Name = name, Title = name, Type = "External", Version = "", Location = Utilities.PathCombine(root.Parent.ToString(), Path.DirectorySeparatorChar.ToString()) });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return templates;
|
return templates;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -137,6 +137,8 @@ namespace Oqtane.Controllers
|
||||||
var templates = new List<Template>();
|
var templates = new List<Template>();
|
||||||
var root = Directory.GetParent(_environment.ContentRootPath);
|
var root = Directory.GetParent(_environment.ContentRootPath);
|
||||||
string templatePath = Utilities.PathCombine(_environment.WebRootPath, "Themes", "Templates", Path.DirectorySeparatorChar.ToString());
|
string templatePath = Utilities.PathCombine(_environment.WebRootPath, "Themes", "Templates", Path.DirectorySeparatorChar.ToString());
|
||||||
|
if (Directory.Exists(templatePath))
|
||||||
|
{
|
||||||
foreach (string directory in Directory.GetDirectories(templatePath))
|
foreach (string directory in Directory.GetDirectories(templatePath))
|
||||||
{
|
{
|
||||||
string name = directory.Replace(templatePath, "");
|
string name = directory.Replace(templatePath, "");
|
||||||
|
@ -156,6 +158,7 @@ namespace Oqtane.Controllers
|
||||||
templates.Add(new Template { Name = name, Title = name, Type = "External", Version = "", Location = Utilities.PathCombine(root.Parent.ToString(), Path.DirectorySeparatorChar.ToString()) });
|
templates.Add(new Template { Name = name, Title = name, Type = "External", Version = "", Location = Utilities.PathCombine(root.Parent.ToString(), Path.DirectorySeparatorChar.ToString()) });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return templates;
|
return templates;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -133,35 +133,6 @@ namespace Oqtane.SiteTemplates
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
_pageTemplates.Add(new PageTemplate
|
|
||||||
{
|
|
||||||
Name = "Develop",
|
|
||||||
Parent = "",
|
|
||||||
Order = 7,
|
|
||||||
Path = "develop",
|
|
||||||
Icon = "oi oi-wrench",
|
|
||||||
IsNavigation = true,
|
|
||||||
IsPersonalizable = false,
|
|
||||||
PermissionList = new List<Permission> {
|
|
||||||
new Permission(PermissionNames.View, RoleNames.Host, true),
|
|
||||||
new Permission(PermissionNames.Edit, RoleNames.Host, true)
|
|
||||||
},
|
|
||||||
PageTemplateModules = new List<PageTemplateModule> {
|
|
||||||
new PageTemplateModule { ModuleDefinitionName = "Oqtane.Modules.HtmlText, Oqtane.Client", Title = "Software Development", Pane = PaneNames.Default,
|
|
||||||
PermissionList = new List<Permission> {
|
|
||||||
new Permission(PermissionNames.View, RoleNames.Host, true),
|
|
||||||
new Permission(PermissionNames.Edit, RoleNames.Host, true)
|
|
||||||
},
|
|
||||||
Content = "<p>Oqtane offers a Module Creator which allows you to create new modules to extend the framework with additional capabilities. Simply provide some basic information and the system will scaffold a completely functional module which includes all of the necessary code files and assets to get you up and running as quickly as possible.</p>"
|
|
||||||
},
|
|
||||||
new PageTemplateModule { ModuleDefinitionName = "Oqtane.Modules.Admin.ModuleCreator, Oqtane.Client", Title = "Module Creator", Pane = PaneNames.Default,
|
|
||||||
PermissionList = new List<Permission> {
|
|
||||||
new Permission(PermissionNames.View, RoleNames.Host, true),
|
|
||||||
new Permission(PermissionNames.Edit, RoleNames.Host, true)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
if (System.IO.File.Exists(Path.Combine(_environment.WebRootPath, "images", "logo-white.png")))
|
if (System.IO.File.Exists(Path.Combine(_environment.WebRootPath, "images", "logo-white.png")))
|
||||||
{
|
{
|
||||||
|
|
BIN
Oqtane.Server/wwwroot/package.png
Normal file
BIN
Oqtane.Server/wwwroot/package.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 5.7 KiB |
|
@ -133,7 +133,7 @@ namespace Oqtane.Shared
|
||||||
var url = (alias != null && !string.IsNullOrEmpty(alias.Path)) ? "/" + alias.Path : "";
|
var url = (alias != null && !string.IsNullOrEmpty(alias.Path)) ? "/" + alias.Path : "";
|
||||||
mode = string.IsNullOrEmpty(mode) ? "crop" : mode;
|
mode = string.IsNullOrEmpty(mode) ? "crop" : mode;
|
||||||
position = string.IsNullOrEmpty(position) ? "center" : position;
|
position = string.IsNullOrEmpty(position) ? "center" : position;
|
||||||
background = string.IsNullOrEmpty(background) ? "000000" : background;
|
background = string.IsNullOrEmpty(background) ? "transparent" : background;
|
||||||
return $"{alias?.BaseUrl}{url}{Constants.ImageUrl}{fileId}/{width}/{height}/{mode}/{position}/{background}/{rotate}/{recreate}";
|
return $"{alias?.BaseUrl}{url}{Constants.ImageUrl}{fileId}/{width}/{height}/{mode}/{position}/{background}/{rotate}/{recreate}";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user