Skip to content

Commit

Permalink
šŸ› fix(DataTable): selected items should not be reset in server-side pā€¦
Browse files Browse the repository at this point in the history
ā€¦agination (#2272)
  • Loading branch information
capdiem authored Dec 5, 2024
1 parent c012ce4 commit 317906d
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 36 deletions.
63 changes: 30 additions & 33 deletions src/Masa.Blazor/Components/DataIterator/MDataIterator.razor.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
ļ»ænamespace Masa.Blazor;
ļ»æusing Masa.Blazor.Components.DataTable;

namespace Masa.Blazor;

// public class MDataIterator<TItem> : BDataIterator<TItem>, IDataIterator<TItem>, ILoadable
public partial class MDataIterator<TItem> : MData<TItem>
Expand Down Expand Up @@ -110,21 +112,18 @@ public partial class MDataIterator<TItem> : MData<TItem>

private IEnumerable<TItem>? _prevValue;
private IEnumerable<string>? _prevSelected;
private IEnumerable<TItem>? _prevExpanded;

public bool EveryItem => SelectableItems.Any() && SelectableItems.All(IsSelected);

public bool SomeItems => SelectableItems.Any(IsSelected);

public IEnumerable<TItem> SelectableItems => ComputedItems.Where(IsSelectable);

private IEnumerable<TItem>? _prevExpanded;

public bool IsEmpty => !Items.Any() || Pagination.ItemsLength == 0;
private Dictionary<string, bool> Expansion { get; set; } = new();

protected Dictionary<string, bool> Expansion { get; private set; } = new();
private Dictionary<SelectionKey<TItem>, bool> Selection { get; } = new();

protected Dictionary<string, bool> Selection { get; } = new();

protected override void OnInitialized()
{
base.OnInitialized();
Expand Down Expand Up @@ -168,18 +167,19 @@ private void UpdateSelection(bool init = false)
var key = ItemKey?.Invoke(item);
if (key is null) continue;

Selection[key] = true;

SelectionKey<TItem> selectionKeyKey = new(key, item);
Selection[selectionKeyKey] = true;
keys.Add(key);
}
}
else if (Selected is not null)
{
keys = [];
foreach (var item in Selected)
foreach (var key in Selected)
{
Selection[item] = true;
keys.Add(item);
SelectionKey<TItem> selectionKeyKey = new(key, default);
Selection[selectionKeyKey] = true;
keys.Add(key);
}
}

Expand All @@ -191,7 +191,7 @@ private void UpdateSelection(bool init = false)
// Unselect those in selection but not in Value when updating Value
foreach (var (key, _) in Selection)
{
Selection[key] = keys.Contains(key);
Selection[key] = keys.Contains(key.Key);
}
}

Expand All @@ -202,7 +202,7 @@ protected override IEnumerable<string> BuildComponentClass()
yield return _block.Name;
}

public bool IsExpanded(TItem item)
protected bool IsExpanded(TItem item)
{
var key = ItemKey?.Invoke(item);
if (string.IsNullOrEmpty(key))
Expand All @@ -227,7 +227,7 @@ public bool IsExpanded(TItem item)
return Expansion.TryGetValue(key, out var expanded) && expanded;
}

public void Expand(TItem item, bool value = true)
protected void Expand(TItem item, bool value = true)
{
if (SingleExpand)
{
Expand Down Expand Up @@ -258,23 +258,19 @@ public void Expand(TItem item, bool value = true)
ExpandedChanged.InvokeAsync(expanded);
}

public bool IsSelected(TItem item)
protected bool IsSelected(TItem item)
{
var key = ItemKey?.Invoke(item);
if (key == null)
{
return false;
}

if (Selection.TryGetValue(key, out var selected))
{
return selected;
}

return false;
SelectionKey<TItem> selectionKey = new(key, item);
return Selection.GetValueOrDefault(selectionKey, false);
}

public void Select(TItem item, bool value = true)
protected void Select(TItem item, bool value = true)
{
if (!IsSelectable(item))
{
Expand All @@ -292,25 +288,28 @@ public void Select(TItem item, bool value = true)
throw new InvalidOperationException("ItemKey or key should not be null");
}

Selection[key] = value;
SelectionKey<TItem> selectionKey = new(key, item);

Selection[selectionKey] = value;

UpdateSelectedItemsAsValue();

OnItemSelect.InvokeAsync((item, value));
}

public bool IsSelectable(TItem item)
protected bool IsSelectable(TItem item)
{
return SelectableKey?.Invoke(item) is null or true;
}

public void ToggleSelectAll(bool value)
protected void ToggleSelectAll(bool value)
{
foreach (var item in SelectableItems)
{
var key = ItemKey?.Invoke(item);
if (key == null) continue;
Selection[key] = value;
SelectionKey<TItem> selectionKey = new(key, item);
Selection[selectionKey] = value;
}

UpdateSelectedItemsAsValue();
Expand All @@ -320,17 +319,15 @@ public void ToggleSelectAll(bool value)

private void UpdateSelectedItemsAsValue()
{
var selectedItems = Items.Where(IsSelected);
var selected = Selection.Where(u => u.Value).ToList();

if (ValueChanged.HasDelegate)
{
ValueChanged.InvokeAsync(selectedItems);
_ = ValueChanged.InvokeAsync(selected.Select(u => u.Key.Item)!);
}

var selected = selectedItems.Select(ItemKey);
if (SelectedChanged.HasDelegate)
else if (SelectedChanged.HasDelegate)
{
SelectedChanged.InvokeAsync(selected);
_ = SelectedChanged.InvokeAsync(selected.Select(u => u.Key.Key));
}
}
}
16 changes: 16 additions & 0 deletions src/Masa.Blazor/Components/DataIterator/SelectionKey.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
ļ»ænamespace Masa.Blazor.Components.DataTable;

public record SelectionKey<TItem>(string Key, TItem? Item)
{
public virtual bool Equals(SelectionKey<TItem>? other)
{
if (ReferenceEquals(null, other)) return false;
if (ReferenceEquals(this, other)) return true;
return Key == other.Key;
}

public override int GetHashCode()
{
return Key.GetHashCode();
}
}
6 changes: 3 additions & 3 deletions src/Masa.Blazor/Components/DataTable/MDataTable.razor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -402,19 +402,19 @@ private void MasaBlazorWindowSizeChanged(object? sender, WindowSizeChangedEventA
InvokeAsync(StateHasChanged);
}

public Task HandleOnRowClickAsync(MouseEventArgs args, TItem item)
private Task HandleOnRowClickAsync(MouseEventArgs args, TItem item)
{
var rowMouseEventArgs = new DataTableRowMouseEventArgs<TItem>(item, IsMobile, IsSelected(item), IsExpanded(item), args);
return OnRowClick.InvokeAsync(rowMouseEventArgs);
}

public Task HandleOnRowContextmenuAsync(MouseEventArgs args, TItem item)
private Task HandleOnRowContextmenuAsync(MouseEventArgs args, TItem item)
{
var rowMouseEventArgs = new DataTableRowMouseEventArgs<TItem>(item, IsMobile, IsSelected(item), IsExpanded(item), args);
return OnRowContextmenu.InvokeAsync(rowMouseEventArgs);
}

public Task HandleOnRowDblClickAsync(MouseEventArgs args, TItem item)
private Task HandleOnRowDblClickAsync(MouseEventArgs args, TItem item)
{
var rowMouseEventArgs = new DataTableRowMouseEventArgs<TItem>(item, IsMobile, IsSelected(item), IsExpanded(item), args);
var e = OnRowDblClick.HasDelegate ? OnRowDblClick : OnRowDbClick;
Expand Down

0 comments on commit 317906d

Please sign in to comment.