using System.Diagnostics.CodeAnalysis; using Connected.Extensions; namespace Connected.Components; public abstract class TableContext { public TableBase Table { get; set; } public Action TableStateHasChanged { get; set; } public Action PagerStateHasChanged { get; set; } public bool HasPager { get; set; } public abstract void Add(Tr row, object item); public abstract void Remove(Tr row, object item); public abstract void UpdateRowCheckBoxes(bool notify = true); public List HeaderRows { get; set; } = new List(); public List FooterRows { get; set; } = new List(); public abstract void InitializeSorting(); public abstract string SortFieldLabel { get; internal set; } public abstract SortDirection SortDirection { get; protected set; } public abstract void ManagePreviousEditedRow(Tr row); } public class TableContext<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] T> : TableContext { private Tr editedRow; public IEqualityComparer Comparer //when the comparer value is setup, update the collections with the new comparer { get => _comparer; set { _comparer = value; Selection = new HashSet(Selection, _comparer); Rows = new Dictionary(Rows, _comparer); } } private IEqualityComparer _comparer; public HashSet Selection { get; set; } = new HashSet(); public Dictionary Rows { get; set; } = new Dictionary(); public List> GroupRows { get; set; } = new List>(); public List> SortLabels { get; set; } = new List>(); public override void UpdateRowCheckBoxes(bool notify = true) { if (!Table.MultiSelection) return; // update row checkboxes foreach (var pair in Rows.ToArray()) { var row = pair.Value; var item = pair.Key; row.SetChecked(Selection.Contains(item), notify: notify); } //update group checkboxes foreach (var row in GroupRows) { var rowGroupItems = row.Items.ToList(); row.SetChecked(Selection.Intersect(rowGroupItems).Count() == rowGroupItems.Count, notify: false); } if (HeaderRows.Count > 0 || FooterRows.Count > 0) { var itemsCount = Table.GetFilteredItemsCount(); var b = Selection.Count == itemsCount && itemsCount != 0; // update header checkbox foreach (var header in HeaderRows) header.SetChecked(b, notify: false); // update footer checkbox foreach (var footer in FooterRows) footer.SetChecked(b, notify: false); } } public override void ManagePreviousEditedRow(Tr row) { if (Table.IsEditable) { // Reset edition values of the edited row // if another row is selected for edition if (editedRow != null && row != editedRow) { editedRow.ManagePreviousEdition(); } // The selected row is the edited row editedRow = row; } } public override void Add(Tr row, object item) { var t = item.As(); if (t is null) return; Rows[t] = row; } public override void Remove(Tr row, object item) { var t = item.As(); if (t is null) return; if (Rows[t] == row) Rows.Remove(t); if (!Table.ContainsItem(item)) { Selection.Remove(t); Table.UpdateSelection(); } } #region --> Sorting public override SortDirection SortDirection { get; protected set; } public Func SortBy { get; protected set; } public TableSortLabel CurrentSortLabel { get; protected set; } public async Task SetSortFunc(TableSortLabel label, bool override_direction_none = false) { CurrentSortLabel = label; if (label.SortDirection == SortDirection.None && override_direction_none) label.SetSortDirection(SortDirection.Ascending); SortDirection = label.SortDirection; SortBy = label.SortBy; UpdateSortLabels(label); if (Table.HasServerData) await Table.InvokeServerLoadFunc(); TableStateHasChanged(); } public IEnumerable Sort(IEnumerable items) { if (items == null) return items; if (SortBy == null || SortDirection == SortDirection.None) return items; if (SortDirection == SortDirection.Ascending) return items.OrderBy(item => SortBy(item)); else return items.OrderByDescending(item => SortBy(item)); } public override void InitializeSorting() { var initial_sortlabel = SortLabels.FirstOrDefault(x => x.InitialDirection != SortDirection.None); if (initial_sortlabel == null) return; CurrentSortLabel = initial_sortlabel; UpdateSortLabels(initial_sortlabel); // this will trigger initial sorting of the table initial_sortlabel.SetSortDirection(initial_sortlabel.InitialDirection); SortDirection = initial_sortlabel.SortDirection; SortBy = initial_sortlabel.SortBy; TableStateHasChanged(); } private void UpdateSortLabels(TableSortLabel label) { foreach (var x in SortLabels) { if (x != label) x.SetSortDirection(SortDirection.None); } } public override string SortFieldLabel { get; internal set; } #endregion }