update Module and Theme Install UI to match Marketplace - including logos and support for sorting
This commit is contained in:
@ -10,61 +10,106 @@
|
||||
<TabStrip>
|
||||
<TabPanel Name="Download" ResourceKey="Download">
|
||||
<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">
|
||||
<select id="price" class="form-select custom-select" @onchange="(e => PriceChanged(e))">
|
||||
<option value="free">@SharedLocalizer["Free"]</option>
|
||||
<option value="paid">@SharedLocalizer["Paid"]</option>
|
||||
</select>
|
||||
<span class="input-group-text">Product</span>
|
||||
<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-secondary" @onclick="Reset">@SharedLocalizer["Reset"]</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@if (_packages != null)
|
||||
{
|
||||
if (_packages.Count > 0)
|
||||
{
|
||||
<Pager Items="@_packages">
|
||||
<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>
|
||||
<td style="width: 1px; vertical-align: middle;">
|
||||
@if (context.Price != null && !string.IsNullOrEmpty(context.PaymentUrl))
|
||||
{
|
||||
<a class="btn btn-primary" style="text-decoration: none !important" href="@context.PaymentUrl" target="_new">@context.Price.Value.ToString("$#,##0.00")</a>
|
||||
}
|
||||
else
|
||||
{
|
||||
<button type="button" class="btn btn-primary" @onclick=@(async () => await GetPackage(context.PackageId, context.Version))>@SharedLocalizer["Download"]</button>
|
||||
}
|
||||
</td>
|
||||
</Row>
|
||||
</Pager>
|
||||
}
|
||||
else
|
||||
{
|
||||
<br />
|
||||
<div class="mx-auto text-center">
|
||||
@Localizer["Search.NoResults"]
|
||||
</div>
|
||||
}
|
||||
}
|
||||
<div class="row mb-3">
|
||||
<div class="col">
|
||||
@if (_initialized)
|
||||
{
|
||||
<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")
|
||||
{
|
||||
<option value="price">@SharedLocalizer["Search.Price"]</option>
|
||||
}
|
||||
</select>
|
||||
</div>
|
||||
</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)
|
||||
{
|
||||
<img src="@GetLogo(context.LogoFileId.Value)" class="img-fluid" alt="@context.Name" />
|
||||
}
|
||||
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>
|
||||
}
|
||||
@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>
|
||||
</Pager>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
<br />
|
||||
<ModuleMessage Type="MessageType.Info" Message="@SharedLocalizer["Oqtane.Marketplace"]" />
|
||||
</TabPanel>
|
||||
@ -116,8 +161,10 @@
|
||||
<NavLink class="btn btn-secondary" href="@NavigateUrl()">@SharedLocalizer["Cancel"]</NavLink>
|
||||
|
||||
@code {
|
||||
private bool _initialized = false;
|
||||
private List<Package> _packages;
|
||||
private string _price = "free";
|
||||
private string _sort = "popularity";
|
||||
private string _search = "";
|
||||
private string _productname = "";
|
||||
private string _packageid = "";
|
||||
@ -131,6 +178,7 @@
|
||||
try
|
||||
{
|
||||
await LoadModuleDefinitions();
|
||||
_initialized = true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@ -141,8 +189,10 @@
|
||||
|
||||
private async Task LoadModuleDefinitions()
|
||||
{
|
||||
ShowProgressIndicator();
|
||||
|
||||
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)
|
||||
{
|
||||
@ -154,21 +204,22 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
HideProgressIndicator();
|
||||
}
|
||||
|
||||
private async void PriceChanged(ChangeEventArgs e)
|
||||
private string GetLogo(int fileid)
|
||||
{
|
||||
try
|
||||
{
|
||||
_price = (string)e.Value;
|
||||
_search = "";
|
||||
await LoadModuleDefinitions();
|
||||
StateHasChanged();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await logger.LogError(ex, "Error On PriceChanged");
|
||||
}
|
||||
var url = ImageUrl(fileid, 100, 100, "", "", "ffffff", 0, false);
|
||||
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 = price;
|
||||
await LoadModuleDefinitions();
|
||||
StateHasChanged();
|
||||
}
|
||||
|
||||
private async Task Search()
|
||||
@ -196,6 +247,12 @@
|
||||
}
|
||||
}
|
||||
|
||||
private async void SortChanged(ChangeEventArgs e)
|
||||
{
|
||||
_sort = (string)e.Value;
|
||||
await LoadModuleDefinitions();
|
||||
}
|
||||
|
||||
private void HideModal()
|
||||
{
|
||||
_productname = "";
|
||||
|
Reference in New Issue
Block a user