Simplified column picker and added defaults. Made tables responsive.

This commit is contained in:
Pat Hartl 2023-09-04 02:02:53 -05:00
parent bd2da60792
commit 804c0c3b6e
8 changed files with 148 additions and 180 deletions

View file

@ -1,11 +0,0 @@
using AntDesign;
using Microsoft.AspNetCore.Components;
namespace LANCommander.Components.Table
{
public interface IPickableColumn : IColumn
{
public bool Visible { get; set; }
public EventCallback<bool> VisibleChanged { get; set; }
}
}

View file

@ -1,13 +0,0 @@
@typeparam TData
@inherits Column<TData>
@implements IPickableColumn
@if (Visible)
{
base.BuildRenderTree(__builder);
}
@code {
[Parameter] public bool Visible { get; set; } = true;
[Parameter] public EventCallback<bool> VisibleChanged { get; set; }
}

View file

@ -1,14 +0,0 @@
@typeparam TItem
@typeparam TProp
@inherits PropertyColumn<TItem, TProp>
@implements IPickableColumn
@if (Visible)
{
base.BuildRenderTree(__builder);
}
@code {
[Parameter] public bool Visible { get; set; } = true;
[Parameter] public EventCallback<bool> VisibleChanged { get; set; }
}

View file

@ -0,0 +1,72 @@
@using Microsoft.AspNetCore.Components.Server.ProtectedBrowserStorage;
@inject ProtectedLocalStorage BrowserStorage
<Drawer Closable="true" Visible="@Visible" Placement="right" Title="@("Columns")" OnClose="() => Close()">
<Space Direction="@DirectionVHType.Vertical">
@foreach (var column in ColumnVisibility.Keys)
{
<SpaceItem>
<Switch Checked="ColumnVisibility[column]" OnChange="(state) => ChangeColumnVisibility(column, state)" /> @column
</SpaceItem>
}
</Space>
</Drawer>
@code {
[Parameter] public string Key { get; set; }
[Parameter] public bool Visible { get; set; }
[Parameter] public EventCallback<bool> VisibleChanged { get; set; }
Dictionary<string, bool> ColumnVisibility = new Dictionary<string, bool>();
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender)
{
try
{
var storedColumnVisibility = await BrowserStorage.GetAsync<Dictionary<string, bool>>($"Views.{Key}.ColumnPicker");
if (storedColumnVisibility.Success && storedColumnVisibility.Value != null)
ColumnVisibility = storedColumnVisibility.Value;
StateHasChanged();
}
catch
{
ColumnVisibility = new Dictionary<string, bool>();
await BrowserStorage.SetAsync($"Views.{Key}.FieldPicker", ColumnVisibility);
}
}
}
public bool IsColumnHidden(string columnName, bool isDefault = true)
{
if (!ColumnVisibility.ContainsKey(columnName))
ColumnVisibility[columnName] = isDefault;
return !ColumnVisibility[columnName];
}
protected override void OnParametersSet()
{
base.OnParametersSet();
if (ColumnVisibility == null)
ColumnVisibility = new Dictionary<string, bool>();
}
async Task ChangeColumnVisibility(string column, bool state)
{
ColumnVisibility[column] = state;
await InvokeAsync(StateHasChanged);
}
async Task Close()
{
Visible = false;
await VisibleChanged.InvokeAsync();
}
}

View file

@ -1,85 +0,0 @@
@using Microsoft.AspNetCore.Components.Server.ProtectedBrowserStorage;
@typeparam TItem
@inject ProtectedLocalStorage BrowserStorage
@if (Table != null)
{
<Drawer Closable="true" Visible="@Visible" Placement="right" Title="@("Fields")" OnClose="() => Close()">
<Space Direction="@DirectionVHType.Vertical">
@foreach (IPickableColumn column in Table.ColumnContext.HeaderColumns.Where(c => !String.IsNullOrWhiteSpace(c.Title) && typeof(IPickableColumn).IsAssignableFrom(c.GetType())))
{
<SpaceItem>
<Switch @bind-Checked="column.Visible" OnChange="(state) => ChangeColumnVisibility(column, state)" /> @column.Title
</SpaceItem>
}
</Space>
</Drawer>
}
@code {
[Parameter] public Table<TItem> Table { get; set; }
[Parameter] public string Key { get; set; }
[Parameter] public bool Visible { get; set; }
[Parameter] public EventCallback<bool> VisibleChanged { get; set; }
Dictionary<int, bool> ColumnVisibility { get; set; }
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender)
{
try
{
var storedColumnVisibility = await BrowserStorage.GetAsync<Dictionary<int, bool>>($"Views.{Key}.FieldPicker");
if (storedColumnVisibility.Success && storedColumnVisibility.Value != null)
ColumnVisibility = storedColumnVisibility.Value;
StateHasChanged();
}
catch
{
ColumnVisibility = new Dictionary<int, bool>();
await BrowserStorage.SetAsync($"Views.{Key}.FieldPicker", ColumnVisibility);
}
}
}
protected override void OnParametersSet()
{
base.OnParametersSet();
if (ColumnVisibility == null)
ColumnVisibility = new Dictionary<int, bool>();
if (Table != null)
{
foreach (ColumnBase column in Table.ColumnContext.HeaderColumns)
{
ColumnVisibility[column.ColIndex] = !column.Hidden;
}
}
}
async Task ChangeColumnVisibility(IPickableColumn column, bool state)
{
//ColumnVisibility[1] = state;
//await BrowserStorage.SetAsync($"Views.{Key}.FieldPicker", ColumnVisibility);
var pickableColumn = Table.ColumnContext.Columns[column.ColIndex] as IPickableColumn;
pickableColumn.Visible = state;
await pickableColumn.VisibleChanged.InvokeAsync();
await InvokeAsync(StateHasChanged);
}
async Task Close()
{
Visible = false;
await VisibleChanged.InvokeAsync();
}
}

View file

@ -21,79 +21,79 @@
</PageHeaderExtra> </PageHeaderExtra>
</PageHeader> </PageHeader>
<TableCustomizer @ref="TableCustomizer" TItem="Game" Table="Table" Key="Games" @bind-Visible="FieldPickerVisible" /> <TableColumnPicker @ref="Picker" Key="Games" @bind-Visible="ColumnPickerVisible" />
<Table @ref="Table" TItem="Game" DataSource="@Games" Loading="@Loading" PageSize="25"> <Table TItem="Game" DataSource="@Games" Loading="@Loading" PageSize="25" Responsive>
<PickableColumn TData="string" Title="Icon"> <Column TData="string" Title="Icon" Hidden="@(Picker.IsColumnHidden("Icon"))">
<Image Src="@GetIcon(context)" Height="32" Width="32" Preview="false"></Image> <Image Src="@GetIcon(context)" Height="32" Width="32" Preview="false"></Image>
</PickableColumn> </Column>
<PickablePropertyColumn Property="g => g.Title" Sortable Filterable /> <PropertyColumn Property="g => g.Title" Sortable Filterable Hidden="@(Picker.IsColumnHidden("Title"))" />
<PickablePropertyColumn Property="g => g.SortTitle" Title="Sort Title" Sortable Filterable /> <PropertyColumn Property="g => g.SortTitle" Title="Sort Title" Sortable Filterable Hidden="@(Picker.IsColumnHidden("Sort Title", false))" />
<PickablePropertyColumn Property="g => g.ReleasedOn" Format="MM/dd/yyyy" Sortable Filterable /> <PropertyColumn Property="g => g.ReleasedOn" Format="MM/dd/yyyy" Sortable Filterable Hidden="@(Picker.IsColumnHidden("Released On"))" />
<PickablePropertyColumn Property="g => g.CreatedOn" Format="MM/dd/yyyy hh:mm tt" Sortable /> <PropertyColumn Property="g => g.CreatedOn" Format="MM/dd/yyyy hh:mm tt" Sortable Hidden="@(Picker.IsColumnHidden("Created On"))" />
<PickablePropertyColumn Property="g => g.CreatedBy" Sortable> <PropertyColumn Property="g => g.CreatedBy" Sortable Hidden="@(Picker.IsColumnHidden("Created By"))">
@context.CreatedBy?.UserName @context.CreatedBy?.UserName
</PickablePropertyColumn> </PropertyColumn>
<PickablePropertyColumn Property="g => g.UpdatedOn" Format="MM/dd/yyyy hh:mm tt" Sortable /> <PropertyColumn Property="g => g.UpdatedOn" Format="MM/dd/yyyy hh:mm tt" Sortable Hidden="@(Picker.IsColumnHidden("Updated On", false))" />
<PickablePropertyColumn Property="g => g.UpdatedBy" Sortable> <PropertyColumn Property="g => g.UpdatedBy" Sortable Hidden="@(Picker.IsColumnHidden("Updated By", false))">
@context.UpdatedBy?.UserName @context.UpdatedBy?.UserName
</PickablePropertyColumn> </PropertyColumn>
<PickablePropertyColumn Property="g => g.Singleplayer" Sortable Filterable> <PropertyColumn Property="g => g.Singleplayer" Sortable Filterable Hidden="@(Picker.IsColumnHidden("Singleplayer", false))">
<Checkbox Disabled="true" Checked="context.Singleplayer" /> <Checkbox Disabled="true" Checked="context.Singleplayer" />
</PickablePropertyColumn> </PropertyColumn>
<PickableColumn TData="bool" Title="Multiplayer"> <Column TData="bool" Title="Multiplayer" Hidden="@(Picker.IsColumnHidden("Multiplayer", false))">
<Checkbox Disabled="true" Checked="context.MultiplayerModes?.Count > 0" /> <Checkbox Disabled="true" Checked="context.MultiplayerModes?.Count > 0" />
</PickableColumn> </Column>
<PickableColumn TData="int" Title="Total Keys"> <Column TData="int" Title="Total Keys" Hidden="@(Picker.IsColumnHidden("Total Keys"))">
@context.Keys?.Count @context.Keys?.Count
</PickableColumn> </Column>
<PickableColumn TData="int" Title="Keys Allocated"> <Column TData="int" Title="Keys Allocated" Hidden="@(Picker.IsColumnHidden("Keys Allocated"))">
@context.Keys?.Count(k => k.ClaimedOn.HasValue) @context.Keys?.Count(k => k.ClaimedOn.HasValue)
</PickableColumn> </Column>
<PickableColumn TData="string[]" Title="Developers"> <Column TData="string[]" Title="Developers" Hidden="@(Picker.IsColumnHidden("Developers", false))">
@foreach (var dev in context.Developers) @foreach (var dev in context.Developers)
{ {
<Tag>@dev.Name</Tag> <Tag>@dev.Name</Tag>
} }
</PickableColumn> </Column>
<PickableColumn TData="string[]" Title="Publishers"> <Column TData="string[]" Title="Publishers" Hidden="@(Picker.IsColumnHidden("Publishers", false))">
@foreach (var pub in context.Publishers) @foreach (var pub in context.Publishers)
{ {
<Tag>@pub.Name</Tag> <Tag>@pub.Name</Tag>
} }
</PickableColumn> </Column>
<PickableColumn TData="string[]" Title="Genres"> <Column TData="string[]" Title="Genres" Hidden="@(Picker.IsColumnHidden("Genres", false))">
@foreach (var genre in context.Genres) @foreach (var genre in context.Genres)
{ {
<Tag>@genre.Name</Tag> <Tag>@genre.Name</Tag>
} }
</PickableColumn> </Column>
<PickableColumn TData="Data.Enums.MultiplayerType[]" Title="Multiplayer Modes"> <Column TData="Data.Enums.MultiplayerType[]" Title="Multiplayer Modes" Hidden="@(Picker.IsColumnHidden("Multiplayer Modes"))">
@foreach (var mode in context.MultiplayerModes.Select(mm => mm.Type).Distinct()) @foreach (var mode in context.MultiplayerModes.Select(mm => mm.Type).Distinct())
{ {
<Tag>@mode.GetDisplayName()</Tag> <Tag>@mode.GetDisplayName()</Tag>
} }
</PickableColumn> </Column>
<ActionColumn Title="" Style="text-align: right"> <ActionColumn Title="" Style="text-align: right">
<TitleTemplate> <TitleTemplate>
<div style="text-align: right"> <div style="text-align: right">
<Button Icon="@IconType.Outline.Edit" Type="@ButtonType.Text" OnClick="() => OpenFieldPicker()" /> <Button Icon="@IconType.Outline.Edit" Type="@ButtonType.Text" OnClick="() => OpenColumnPicker()" />
</div> </div>
</TitleTemplate> </TitleTemplate>
<ChildContent> <ChildContent>
@ -118,14 +118,13 @@
IEnumerable<Game> Games { get; set; } = new List<Game>(); IEnumerable<Game> Games { get; set; } = new List<Game>();
bool Loading = true; bool Loading = true;
bool FieldPickerVisible = false;
string Search = ""; string Search = "";
Table<Game> Table; bool Visibility = false;
TableCustomizer<Game> TableCustomizer;
Dictionary<int, bool> ColumnVisibility = new Dictionary<int, bool>(); TableColumnPicker Picker;
bool ColumnPickerVisible = false;
protected override async Task OnAfterRenderAsync(bool firstRender) protected override async Task OnAfterRenderAsync(bool firstRender)
{ {
@ -177,13 +176,13 @@
Loading = false; Loading = false;
} }
private async Task OpenFieldPicker() private async Task OpenColumnPicker()
{ {
FieldPickerVisible = true; ColumnPickerVisible = true;
} }
private async Task CloseFieldPicker() private async Task CloseColumnPicker()
{ {
FieldPickerVisible = false; ColumnPickerVisible = false;
} }
} }

View file

@ -29,33 +29,42 @@
</PageHeaderExtra> </PageHeaderExtra>
</PageHeader> </PageHeader>
<Table TItem="Server" DataSource="@Servers" Loading="@Loading" PageSize="25" @bind-SelectedRows="SelectedServers"> <TableColumnPicker @ref="Picker" Key="Servers" @bind-Visible="ColumnPickerVisible" />
<Table TItem="Server" DataSource="@Servers" Loading="@Loading" PageSize="25" @bind-SelectedRows="SelectedServers" Responsive>
<Selection Key="@(context.Id.ToString())" /> <Selection Key="@(context.Id.ToString())" />
<PropertyColumn Property="s => s.Name" Sortable /> <PropertyColumn Property="s => s.Name" Sortable Hidden="@(Picker.IsColumnHidden("Name"))" />
<PropertyColumn Property="s => s.Game"> <PropertyColumn Property="s => s.Game" Hidden="@(Picker.IsColumnHidden("Game"))">
<Image Src="@GetIcon(context.Game)" Height="32" Width="32" Preview="false"></Image> <Image Src="@GetIcon(context.Game)" Height="32" Width="32" Preview="false"></Image>
@context.Game?.Title @context.Game?.Title
</PropertyColumn> </PropertyColumn>
<PropertyColumn Property="s => s.CreatedOn" Format="MM/dd/yyyy hh:mm tt" Sortable /> <PropertyColumn Property="s => s.CreatedOn" Format="MM/dd/yyyy hh:mm tt" Sortable Hidden="@(Picker.IsColumnHidden("Created On"))" />
<PropertyColumn Property="s => s.CreatedBy" Sortable> <PropertyColumn Property="s => s.CreatedBy" Sortable Hidden="@(Picker.IsColumnHidden("Created By"))">
@context.CreatedBy?.UserName @context.CreatedBy?.UserName
</PropertyColumn> </PropertyColumn>
<PropertyColumn Property="g => g.UpdatedOn" Format="MM/dd/yyyy hh:mm tt" Sortable /> <PropertyColumn Property="g => g.UpdatedOn" Format="MM/dd/yyyy hh:mm tt" Sortable Hidden="@(Picker.IsColumnHidden("Updated On"))" />
<PropertyColumn Property="g => g.UpdatedBy" Sortable> <PropertyColumn Property="g => g.UpdatedBy" Sortable Hidden="@(Picker.IsColumnHidden("Updated By"))">
@context.UpdatedBy?.UserName @context.UpdatedBy?.UserName
</PropertyColumn> </PropertyColumn>
<ActionColumn Title="" Style="text-align: right"> <ActionColumn Title="" Style="text-align: right">
<ServerControl ServerId="context.Id" /> <TitleTemplate>
<Space Direction="DirectionVHType.Horizontal"> <div style="text-align: right">
<SpaceItem> <Button Icon="@IconType.Outline.Edit" Type="@ButtonType.Text" OnClick="() => OpenColumnPicker()" />
<Button OnClick="() => Edit(context)">Edit</Button> </div>
</SpaceItem> </TitleTemplate>
<SpaceItem> <ChildContent>
<Popconfirm OnConfirm="() => Delete(context)" Title="Are you sure you want to delete this server?"> <ServerControl ServerId="context.Id" />
<Button Icon="@IconType.Outline.Close" Type="@ButtonType.Text" Danger /> <Space Direction="DirectionVHType.Horizontal">
</Popconfirm> <SpaceItem>
</SpaceItem> <Button OnClick="() => Edit(context)">Edit</Button>
</Space> </SpaceItem>
<SpaceItem>
<Popconfirm OnConfirm="() => Delete(context)" Title="Are you sure you want to delete this server?">
<Button Icon="@IconType.Outline.Close" Type="@ButtonType.Text" Danger />
</Popconfirm>
</SpaceItem>
</Space>
</ChildContent>
</ActionColumn> </ActionColumn>
</Table> </Table>
@ -67,6 +76,8 @@
string Search = ""; string Search = "";
IEnumerable<Server> SelectedServers; IEnumerable<Server> SelectedServers;
TableColumnPicker Picker;
bool ColumnPickerVisible = false;
protected override void OnAfterRender(bool firstRender) protected override void OnAfterRender(bool firstRender)
{ {
@ -140,4 +151,14 @@
ServerProcessService.StopServer(server); ServerProcessService.StopServer(server);
} }
} }
private async Task OpenColumnPicker()
{
ColumnPickerVisible = true;
}
private async Task CloseColumnPicker()
{
ColumnPickerVisible = false;
}
} }

View file

@ -10,7 +10,6 @@
@using BlazorMonaco @using BlazorMonaco
@using BlazorMonaco.Editor @using BlazorMonaco.Editor
@using LANCommander.Components @using LANCommander.Components
@using LANCommander.Components.Table
@using LANCommander.Shared @using LANCommander.Shared
@using LANCommander.Services @using LANCommander.Services
@using LANCommander.Data.Models @using LANCommander.Data.Models