Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: GridSort somewhat incompatible with ItemsProvider #3290

Open
davhdavh opened this issue Feb 2, 2025 · 4 comments
Open

feat: GridSort somewhat incompatible with ItemsProvider #3290

davhdavh opened this issue Feb 2, 2025 · 4 comments
Labels
status:needs-investigation Needs additional investigation

Comments

@davhdavh
Copy link

davhdavh commented Feb 2, 2025

🙋 Feature Request

GridSort assumes the sorting is only possible on columns where the column expression is a MemberExpression to be able to apply it to an IQueryable.

This means that any model used with an ItemsProvider must provider a Member for any sortable property, and that it must somehow map those member names to a sorting method.

💁 Possible Solution

I see 2 possible solutions for this:

a. Add GridSort constructor that allows a arbitrary key to be used as PropertyName, so that SortedProperty.PropertyName can be mapped to the custom sorting logic.

b. Add an optional ColumnKey to each column and allow GridSort to use null for PropertyName, but add the ColumnKey in SortedProperty.

🔦 Context

Have a complex code base where the underlying db model does not support IQueryable and columns are very dynamic.

💻 Examples

<FluentDataGrid ItemsProvider="@ItemsProvider" >
@foreach (var colDef in UserColumns) {
 <PropertyColumn Title="@colDef.CustomUserPropertyName" Property="@(x => colDef.GetValueFor(x))" Sortable="true" SortBy="NotPossible" />
}
</FluentDataGrid>
@microsoft-github-policy-service microsoft-github-policy-service bot added the triage New issue. Needs to be looked at label Feb 2, 2025
@vnbaaij vnbaaij added status:needs-investigation Needs additional investigation and removed triage New issue. Needs to be looked at labels Feb 3, 2025
@PascalVorwerk
Copy link

Just as a possible fix for ur sitation, we have made some extension methods that allows us to send 'nested' properties to our back-end and then sorting will work on 'complex' objects. For example: Person.Bike.Brand would result in the following SortOn query parameter: SortOn=Bike.Brand

We then use expressions and reflection to be able to sort. It is with Entity framework however and also with IQueryable entities, so i am not sure if this would help. Let me know, if needed i can share some code!

@vnbaaij
Copy link
Collaborator

vnbaaij commented Feb 6, 2025

@davhdavh Aspire is already using a construction where a public string? ColumnId {get; set; } is added to every column (they use Aspire...Column which use our PropertyColumn and TemplateColumn as base types). Based on that I' would be inclined to go with your option b).
Not really sure though what the code for GridSort and ``SortedProperty` would then look like. Can you give a suggestion here?

@davhdavh
Copy link
Author

This is how I would approach the problem:

  1. Add ISortableColumn (or change IBindableColumn) and have PropertyColumn inherit from it
public interface ISortableColumn<TGridItem, TProp> : IBindableColumn<TGridItem, TProp> {
  string? ColumnId {get; } 
  IComparer<TProp>? Comparer { get; }
}
  1. Add overloads for ByAscending, ByDescending etc to take a ISortableColumn parameter instead
  2. Change the existing implementations to wrap the expressions in a dummy (ISortableColumn col, bool ascending, bool stickySortOrder)
  3. Change implementation to store (ISortableColumn, bool, bool) rather than raw (LambdaExpression, bool)
  4. Change BuildPropertyList to add ISortableColumn to SortedProperty.Column and move ToPropertyName to SortedProperty, so PropertyName can be lazy evaluated
  5. Fix the implementation so that the BuildPropertyList and Apply/Byxxx does not double implement the direction logic.

@vnbaaij
Copy link
Collaborator

vnbaaij commented Feb 10, 2025

I'm afraid I need a bit more help with the code...

As said, the ColumnId needs to be present on all column types (Property, Template and Select), so probably better to create a separate interface for that? Steps 2-6 are not clear to me. As you seem to have a pretty clear picture of it, why not create a PR?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
status:needs-investigation Needs additional investigation
Projects
None yet
Development

No branches or pull requests

3 participants