Material-Blazor / Material.Blazor

Lightweight Material Theme components for Blazor
Other
248 stars 32 forks source link

MBGridMT requirements #567

Open MarkStega opened 3 years ago

MarkStega commented 3 years ago

MBGridMT is the follow on component to MBGrid using the Material styling and code. It is expected that at the completion of Phase 1 that MBGridMT will become MBGrid and that the original MBGrid code will be deprecated.

MBGridMT Phase 1

Common

Clinical desktop mode

OR Manager mode

MBGridMT Phase 2 Candidates

MarkStega commented 3 years ago

From Stefan and the original MBGrid requirements:

I'd like to add filtering to the wishlist. Ideally, this would include a set of filter methods for common datatypes (string and numerical data) and the ability to extend that with a custom filter dialog and method (I need to work out a nice way to integrate custom filtering, not sure about the syntax yet).

The user should not be required to write a menu component and should not have to deal with how to open/close the menu. All they should provide is the content of the menu. What they need for that is

I'm fairly sure we can design it roughly like this, so that usage looks like:

<Column Header="Column with customized filter">
   <CustomFilterMenuContent>
      @foreach (var item in context.Items)
      {
         <MTCheckbox Value="context.IsVisible(item)"
               ValueChanged="(visible) => { UpdateFilter(context, item, visible); }"/>
      }
   </CustomFilterMenuContent>
</Column>
@code {
  private List<TItem> my_visible_items = new List<TItem>();
  private void UpdateFilter(ColumnFilterContext<TItem> context, TItem item, bool visible)
  {
      if (visible) 
      {
         my_visible_items.Add(item);
      }
      else
      {
         my_visible_items.Remove(item);
      }
      // this is how we could update the filter: we replace the filter predicate
      context.IsVisible = (i) => my_visible_items.Contains(i);
  }
}

This of course is a rather boring filter menu (simply listing all items? come on!)

A more interesting one could be

<Column Header="SomeValue">
   <CustomFilterMenuContent>
      <MTNumericDoubleField Value="threshold"
            ValueChanged="(v) => {threshold = v;  context.IsVisible = (i) => { i.SomeValue > threshold; }; } />
   </CustomFilterMenuContent>
</Column>
@code {
  private double threshold;
}

So I think the definition could be:

public class ColumnFilterContext<TItem>
{
   public IEnumerable<TItem> Items { get; } //  to think about: is IEnumerable a good choice here?
   public Func<TItem, bool> IsVisible { get; set; } = (_) => true; // default state is to have everything visible
}

And for the column:

public partial class Column
{
    [Parameter] public string Header {get;set;}
    [Parameter] public RenderFragment<ColumnFilterContext<TItem>> CustomFilterMenuContent {get;set;}
    //...
}

Disclaimer: none of this code is tested. It wasn't even compiled once, so might contain syntax errors and other issues.