Files
Mf/Mf.Razor/Components/Table.razor
T
2026-04-29 00:53:30 +03:30

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);
}
}