199 lines
No EOL
6.2 KiB
Text
199 lines
No EOL
6.2 KiB
Text
@using AntDesign.TableModels
|
|
@using LANCommander.Server.Data
|
|
@using LANCommander.Server.Models
|
|
@using System.IO.Compression
|
|
@using System.Linq.Expressions
|
|
@using Microsoft.EntityFrameworkCore
|
|
@using System.Web
|
|
@namespace LANCommander.Server.UI.Components
|
|
@attribute [CascadingTypeParameter(nameof(TItem))]
|
|
@typeparam TItem where TItem : BaseModel
|
|
@inherits Table<TItem>
|
|
@inject IDbContextFactory<DatabaseContext> DatabaseContextFactory
|
|
@inject NavigationManager NavigationManager
|
|
@inject DrawerService DrawerService
|
|
|
|
<CascadingValue Value="this">
|
|
<Flex Justify="FlexJustify.SpaceBetween" Style="padding: 12px;">
|
|
<Flex Gap="FlexGap.Small">
|
|
@if (Searchable)
|
|
{
|
|
<Search Placeholder="Search" @bind-Value="Search" BindOnInput DebounceMilliseconds="250"/>
|
|
}
|
|
<Button Icon="@IconType.Outline.Control" Type="@ButtonType.Text" OnClick="OpenDrawer"/>
|
|
@LeftToolbar
|
|
</Flex>
|
|
|
|
@if (RightToolbar != null)
|
|
{
|
|
<Flex Gap="FlexGap.Small">
|
|
@RightToolbar
|
|
</Flex>
|
|
}
|
|
</Flex>
|
|
|
|
<CascadingValue Value="Includes" IsFixed>
|
|
<CascadingValue Value="ColumnVisibility" IsFixed>
|
|
<div id="@Id" class="ant-table-visibility-container">
|
|
@RenderBase()
|
|
</div>
|
|
</CascadingValue>
|
|
</CascadingValue>
|
|
</CascadingValue>
|
|
|
|
<style>
|
|
@foreach (var columnVisibility in ColumnVisibility) {
|
|
if (!columnVisibility.Value)
|
|
{
|
|
@($"#{Id} tbody td:nth-child({columnVisibility.Key + 1}) {{display: none;}}")
|
|
@($"#{Id} thead th:nth-child({columnVisibility.Key + 1}) {{display: none;}}")
|
|
}
|
|
}
|
|
</style>
|
|
|
|
@code {
|
|
[Parameter] public RenderFragment LeftToolbar { get; set; }
|
|
[Parameter] public RenderFragment RightToolbar { get; set; }
|
|
[Parameter] public RenderFragment<TItem> Columns { get; set; }
|
|
[Parameter] public RenderFragment Actions { get; set; }
|
|
[Parameter] public bool Searchable { get; set; }
|
|
[Parameter] public string Search { get; set; }
|
|
[Parameter] public string SearchChanged { get; set; }
|
|
[Parameter] public Expression<Func<TItem, bool>> SearchQuery { get; set; }
|
|
|
|
string Url;
|
|
bool DrawerOpen = false;
|
|
|
|
internal Dictionary<int, bool> ColumnVisibility = new();
|
|
List<string> Includes = new();
|
|
|
|
RenderFragment RenderBase() => builder => base.BuildRenderTree(builder);
|
|
|
|
protected override async Task OnInitializedAsync()
|
|
{
|
|
NavigationManager.LocationChanged += LocationChanged;
|
|
|
|
Url = NavigationManager.Uri;
|
|
|
|
OnChange = EventCallback.Factory.Create<QueryModel<TItem>>(this,
|
|
async (queryModel) =>
|
|
{
|
|
using (var context = DatabaseContextFactory.CreateDbContext())
|
|
{
|
|
var queryable = queryModel != null ? context.Set<TItem>().ExecuteTableQuery(queryModel) : context.Set<TItem>();
|
|
|
|
foreach (var include in Includes)
|
|
{
|
|
queryable = queryable.Include(include);
|
|
}
|
|
|
|
if (!String.IsNullOrWhiteSpace(Search) && SearchQuery != null)
|
|
{
|
|
queryable = queryable.Where(SearchQuery);
|
|
}
|
|
|
|
Total = await queryable.CountAsync();
|
|
|
|
if (queryModel != null)
|
|
DataSource = await queryable.CurrentPagedRecords(queryModel).ToListAsync();
|
|
else
|
|
DataSource = await queryable.Take(PageSize).ToListAsync();
|
|
|
|
await base.OnParametersSetAsync();
|
|
base.OnParametersSet();
|
|
}
|
|
});
|
|
|
|
await OnChange.InvokeAsync();
|
|
|
|
await base.OnInitializedAsync();
|
|
}
|
|
|
|
protected override async Task OnAfterRenderAsync(bool firstRender)
|
|
{
|
|
if (firstRender)
|
|
await OnChange.InvokeAsync();
|
|
}
|
|
|
|
protected override async Task OnParametersSetAsync()
|
|
{
|
|
if (Columns != null)
|
|
ChildContent = Columns;
|
|
|
|
await base.OnParametersSetAsync();
|
|
}
|
|
|
|
async void LocationChanged(object sender, LocationChangedEventArgs e)
|
|
{
|
|
Url = e.Location;
|
|
await LoadTableParameter();
|
|
}
|
|
|
|
async Task LoadTableParameter()
|
|
{
|
|
Loading = true;
|
|
await InvokeStateHasChangedAsync();
|
|
|
|
var uri = NavigationManager.ToAbsoluteUri(Url);
|
|
var query = HttpUtility.ParseQueryString(uri.Query);
|
|
|
|
if (query.AllKeys.Contains("Page"))
|
|
PageIndex = int.TryParse(query["Page"], out var index) ? index > 0 ? index : 1 : 1;
|
|
|
|
if (query.AllKeys.Contains("Size"))
|
|
PageSize = int.TryParse(query["Size"], out var size) ? size > 0 ? size : 50 : 50;
|
|
|
|
if (query["Search"] != null && query["Search"] != Search)
|
|
Search = query["Search"];
|
|
|
|
Loading = false;
|
|
await InvokeStateHasChangedAsync();
|
|
}
|
|
|
|
public async Task OpenDrawer()
|
|
{
|
|
var options = new DrawerOptions
|
|
{
|
|
Title = "Columns",
|
|
Width = "350",
|
|
MaskClosable = false,
|
|
Placement = DrawerPlacement.Right,
|
|
};
|
|
|
|
var columns = new List<DataTableColumn>();
|
|
|
|
foreach (var column in ColumnContext.Columns)
|
|
{
|
|
if (column is not ISelectionColumn && column is not ActionColumn)
|
|
{
|
|
columns.Add(new DataTableColumn
|
|
{
|
|
Index = column.ColIndex,
|
|
Name = column.Title,
|
|
Visible = true
|
|
});
|
|
}
|
|
}
|
|
|
|
columns = (await DrawerService.CreateDialogAsync<DataTableColumnPickerDrawer, IEnumerable<DataTableColumn>, IEnumerable<DataTableColumn>>(options, columns)).ToList();
|
|
|
|
foreach (var column in columns)
|
|
{
|
|
ColumnVisibility[column.Index] = column.Visible;
|
|
}
|
|
|
|
ReloadData(PageIndex, PageSize);
|
|
InvokeStateHasChanged();
|
|
}
|
|
|
|
public void CloseDrawer()
|
|
{
|
|
InvokeStateHasChanged();
|
|
StateHasChanged();
|
|
}
|
|
|
|
public void Dispose()
|
|
{
|
|
NavigationManager.LocationChanged -= LocationChanged;
|
|
}
|
|
} |