groceries/Groceries/Items/ItemsPage.razor

96 lines
3.6 KiB
Plaintext

@using Groceries.Data
@using Microsoft.EntityFrameworkCore
@layout Layout
@inject AppDbContext DbContext
@inject NavigationManager Navigation
@inject IHttpContextAccessor HttpContextAccessor
<PageTitle>Groceries &ndash; Items</PageTitle>
<div class="row">
<h1 class="row__fill">Items</h1>
<SearchForm data-turbo-frame="table" data-turbo-action="advance">
<input type="hidden" name="page" value="1" />
</SearchForm>
</div>
<turbo-frame id="table" target="top">
<section class="table">
<table>
<thead>
<tr>
<th scope="col" class="table__header table__header--shaded">Brand</th>
<th scope="col" class="table__header table__header--shaded" style="width: 100%">Name</th>
<th scope="col" class="table__header table__header--shaded">Last Purchased</th>
<th scope="col" class="table__header table__header--shaded">Barcode</th>
@*<th scope="col" class="table__header table__header--shaded"></th>*@
</tr>
</thead>
<tbody>
@foreach (var item in items)
{
<tr>
<td class="table__cell">@item.Brand</td>
<td class="table__cell">@item.Name</td>
<td class="table__cell">
<time datetime="@item.LastPurchasedAt?.ToString("o")">@item.LastPurchasedAt?.ToLongDateString()</time>
</td>
<td class="table__cell table__cell--icon" style="width: fit-content">@(item.HasBarcode ? "✓" : "")</td>
@*<td class="table__cell">
<a class="link" href="/items/edit/@item.Id">Edit</a>
</td>*@
</tr>
}
</tbody>
</table>
<TablePaginator Model="items" />
</section>
</turbo-frame>
@code {
[SupplyParameterFromQuery]
public int? Page { get; set; }
[SupplyParameterFromQuery]
public string? Search { get; set; }
private record ItemModel(Guid Id, string Brand, string Name, bool HasBarcode, DateTime? LastPurchasedAt);
private ListPageModel<ItemModel> items = ListPageModel.Empty<ItemModel>();
protected override async Task OnParametersSetAsync()
{
var itemsQuery = DbContext.Items.AsQueryable();
if (!string.IsNullOrEmpty(Search))
{
var searchPattern = $"%{Search}%";
itemsQuery = itemsQuery.Where(item => EF.Functions.ILike(item.Brand + ' ' + item.Name, searchPattern));
}
items = await itemsQuery
.OrderBy(item => item.Brand)
.ThenBy(item => item.Name)
.GroupJoin(
DbContext.ItemPurchases.Where(purchase => purchase.IsLastPurchase),
item => item.Id,
lastPurchase => lastPurchase.ItemId,
(item, lastPurchase) => new { item, lastPurchase })
.SelectMany(
group => group.lastPurchase.DefaultIfEmpty(),
(group, lastPurchase) => new ItemModel(
group.item.Id,
group.item.Brand,
group.item.Name,
group.item.Barcodes.Count != 0,
lastPurchase != null ? lastPurchase.CreatedAt : null))
.ToListPageModelAsync(Page.GetValueOrDefault(), cancellationToken: HttpContextAccessor.HttpContext!.RequestAborted);
if (items.Page != Page)
{
Navigation.NavigateTo(Navigation.GetUriWithQueryParameter("page", items.Page));
}
}
}