238 lines
9.3 KiB
Plaintext
238 lines
9.3 KiB
Plaintext
@using System.Reflection
|
|
@using Mf.Core
|
|
@using System.ComponentModel.DataAnnotations.Schema
|
|
@typeparam TItem
|
|
@inject HttpClient httpClient
|
|
@inject IJSRuntime Js
|
|
@inherits BaseForm
|
|
|
|
|
|
@if (IsLoading)
|
|
{
|
|
<Loadingspinner />
|
|
}
|
|
else
|
|
{
|
|
|
|
|
|
|
|
<th colspan="@Columns.Count">
|
|
<input type="text" class="form-control" placeholder="جستجو..." @bind="SearchText" @bind:event="oninput" />
|
|
</th>
|
|
|
|
|
|
|
|
|
|
<div class="table-container">
|
|
<div class="table-scroll">
|
|
<table class="table table-bordered table-hover">
|
|
<thead>
|
|
<tr>
|
|
@foreach (var column in Columns)
|
|
{
|
|
<th class='nowrap-col ' @onclick="() => SortBy(column.Name)">
|
|
@column.GetDisplayName()
|
|
@if (SortColumn == column.Name)
|
|
{
|
|
<span>@(SortAscending ? "▲" : "▼")</span>
|
|
}
|
|
</th>
|
|
}
|
|
<th class="sticky-col-right">عملیات</th>
|
|
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
@foreach (var item in PagedData)
|
|
{
|
|
|
|
<tr>
|
|
|
|
@foreach (var column in Columns)
|
|
{
|
|
@if (column.GetCustomAttribute<HtmlFormatAttribute>() != null && GetPropertyValue(item, column.Name) != null)
|
|
{
|
|
<td>
|
|
@if (((MarkupString)GetPropertyValue(item!, column.Name)!.ToString()!) is MarkupString content)
|
|
{
|
|
<button style="text-overflow:ellipsis;overflow:hidden;max-width:100px;max-height:50px;white-space:nowrap;" type="button" class="btn btn-secondary" data-bs-toggle="tooltip" data-bs-html="true" data-bs-title="@content">@content</button>
|
|
}
|
|
|
|
</td>
|
|
}
|
|
else if (column.GetCustomAttribute<PictureAttribute>() != null)
|
|
{
|
|
<td>
|
|
<img src='@(httpClient.BaseAddress + "api/book-image/" + @GetPropertyValue(item, column.Name) + "?width=50&&height=50")' />
|
|
</td>
|
|
|
|
}
|
|
@* else if (column.PropertyType == typeof(User)) *@
|
|
@* { *@
|
|
@* <td class="nowrap-col"> *@
|
|
@* <button class="btn"> *@
|
|
@* <DisplayUser Id="@Guid.Parse(GetPropertyValue(item, column.GetCustomAttribute<ForeignKeyAttribute>().Name).ToString())" /> *@
|
|
@* </button> *@
|
|
@* </td> *@
|
|
@* *@
|
|
@* } *@
|
|
else if (column.GetCustomAttribute<ForeignKeyAttribute>() != null)
|
|
{
|
|
@if (GetPropertyValue(item, column.GetCustomAttribute<ForeignKeyAttribute>().Name) != null)
|
|
{
|
|
<td class="nowrap-col">
|
|
<button class="btn">
|
|
<DisplayTableName Type="@column.PropertyType" Id="@long.Parse(GetPropertyValue(item, column.GetCustomAttribute<ForeignKeyAttribute>().Name).ToString())" />
|
|
</button>
|
|
@* <Detail Type="@column.PropertyType" Id="@long.Parse(GetPropertyValue(item, column.GetCustomAttribute<ForeignKeyAttribute>().Name).ToString())" /> *@
|
|
</td>
|
|
}
|
|
else
|
|
{
|
|
<td></td>
|
|
}
|
|
|
|
}
|
|
else if (column.GetType().Name == "Guid")
|
|
{
|
|
<td>
|
|
@{
|
|
var content = GetPropertyCustomValue(item, column);
|
|
}
|
|
<button style="text-overflow:ellipsis;overflow:hidden;max-width:100px;max-height:50px;white-space:nowrap;" type="button" class="btn btn-secondary" data-bs-toggle="tooltip" data-bs-html="true" data-bs-title="@content">
|
|
@content
|
|
</button>
|
|
</td>
|
|
}
|
|
else if (column.PropertyType == typeof(bool))
|
|
{
|
|
<td class="nowrap-col">
|
|
@if ((column.GetValue(item).ToString()) == "True")
|
|
{
|
|
<input type="checkbox" checked="checked" value="true" disabled="disabled" />
|
|
}
|
|
</td>
|
|
}
|
|
|
|
else
|
|
{
|
|
<td class="nowrap-col">@GetPropertyCustomValue(item, column)</td>
|
|
}
|
|
}
|
|
|
|
<td class="sticky-col-right">
|
|
<div class="btn-group">
|
|
<button @onclick="async () => await OnUpdate.InvokeAsync(item)" class="btn btn-sm btn-warning">ویرایش</button>
|
|
<button @onclick="async () => await OnDelete.InvokeAsync(item)" class="btn btn-sm btn-danger">حذف</button>
|
|
</div>
|
|
|
|
</td>
|
|
</tr>
|
|
}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
|
|
<nav class="pagination-wrapper">
|
|
<ul class="pagination">
|
|
@foreach (var i in Enumerable.Range(1, TotalPages))
|
|
{
|
|
<li class="page-item @(CurrentPage == i ? "active" : "")">
|
|
<a class="page-link" @onclick="() => GoToPage(i)">@i</a>
|
|
</li>
|
|
}
|
|
</ul>
|
|
</nav>
|
|
</div>
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@code {
|
|
[Parameter] public List<TItem> Data { get; set; } = new();
|
|
[Parameter] public List<PropertyInfo> Columns { get; set; } = new();
|
|
[Parameter] public int PageSize { get; set; } = 5;
|
|
//[Parameter] public List<(string, List<string>)> OtherValues { get; set; } = new();
|
|
[Parameter] public EventCallback<TItem> OnUpdate { get; set; }
|
|
[Parameter] public EventCallback<TItem> OnDelete { get; set; }
|
|
|
|
private int CurrentPage = 1;
|
|
private string SortColumn = "";
|
|
private bool SortAscending = true;
|
|
private string SearchText = "";
|
|
|
|
private IEnumerable<TItem> FilteredData => string.IsNullOrWhiteSpace(SearchText)
|
|
? Data
|
|
: Data.Where(item => Columns.Any(col => GetPropertyValue(item, col.Name)?.ToString()?.Contains(SearchText, StringComparison.OrdinalIgnoreCase) ?? false));
|
|
|
|
private IEnumerable<TItem> SortedData =>
|
|
string.IsNullOrWhiteSpace(SortColumn)
|
|
? FilteredData
|
|
: (SortAscending
|
|
? FilteredData.OrderBy(item => GetPropertyValue(item, SortColumn))
|
|
: FilteredData.OrderByDescending(item => GetPropertyValue(item, SortColumn)));
|
|
|
|
private IEnumerable<TItem> PagedData => SortedData
|
|
.Skip((CurrentPage - 1) * PageSize)
|
|
.Take(PageSize);
|
|
|
|
private int TotalPages => (int)Math.Ceiling((double)SortedData.Count() / PageSize);
|
|
|
|
private void SortBy(string column)
|
|
{
|
|
if (SortColumn == column)
|
|
SortAscending = !SortAscending;
|
|
else
|
|
{
|
|
SortColumn = column;
|
|
SortAscending = true;
|
|
}
|
|
CurrentPage = 1;
|
|
}
|
|
|
|
private void GoToPage(int page)
|
|
{
|
|
CurrentPage = page;
|
|
StateHasChanged();
|
|
}
|
|
|
|
private object? GetPropertyValue(object obj, string propName)
|
|
{
|
|
var ss = obj.GetType().GetProperty(propName)?.GetValue(obj);
|
|
|
|
return obj.GetType().GetProperty(propName)?.GetValue(obj);
|
|
}
|
|
|
|
private object? GetPropertyCustomValue(object obj, PropertyInfo prop)
|
|
{
|
|
return prop.GetCustomValue(obj);
|
|
// var result = obj.GetType().GetProperty(prop.Name)?.GetValue(obj);
|
|
// var attr = prop.GetCustomAttribute<PriceAttriute>();
|
|
// if(attr != null)
|
|
// {
|
|
// result = ((long)result).ToString(attr.Format);
|
|
// }
|
|
|
|
// return result;
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
protected override async Task OnAfterRenderAsync(bool firstRender)
|
|
{
|
|
if (firstRender)
|
|
{
|
|
|
|
}
|
|
|
|
await base.OnAfterRenderAsync(firstRender);
|
|
}
|
|
}
|