Skip to content

MudDataGrid: Refactor FilterDefintions API#29

Merged
tjscience merged 2 commits intotjscience:devfrom
TobiasBreuer:feature/enhance-filterdefinitions
Mar 10, 2022
Merged

MudDataGrid: Refactor FilterDefintions API#29
tjscience merged 2 commits intotjscience:devfrom
TobiasBreuer:feature/enhance-filterdefinitions

Conversation

@TobiasBreuer
Copy link

Description

This PR allows consumers of the Grid to handle FilterDefinitions in a more flexible way.
Especially when using server-side data loading from an arbitrary API, this can come in handy.
The consumer of the grid can decide now within the ServerLoad callback how to serialize the filters so that they can be consumed by the API.

Example below shows handling the Expressions now provided by the FilterDefinitions class.
Alternatively, for sure, the consumer can still fetch the individual properties (e.g Field, Operator, Value etc.) and create its own filter logic if required.

How Has This Been Tested?

Existing Tests in DataGridTests.
Additional Tests for new API method will be added after conclusion of discussion.

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)

Example usage:

private async Task<GridData<Model>> ServerReload(GridState<Model> state)
{
	// via the GridState, the MudDataGrid will provide information on pagination, searching and filtering.
	// The FilterDefinition class allows for retrieving the filter as Expression or as Func<T, bool>.
	// For transfer to an API the easiest approach is to project the definitions to their respective expression
	// And use the ToString() overloaded method of the Expression type to be able to serialize the resolved expression:
	var filterStrings = state.FilterDefinitions.Select(fd => fd.GenerateFilterExpression().ToString());

	// using this List<string> of filters, you can forward this information to the API (usually you will have some sort of RequestDto carrying more information like pagination and sorting)
	var requestDto = CreateRequestDto(..., filterStrings); // some custom logic to create your request model.

	var response = await SomeService.GetModels(requestDto); // fetch data from the API

	// ... Some error handling most likey happening here...

	return new GridData<Model>() { TotalItems = response.TotalRecords, Items = response.Data };
}

// ...
// From the API, you can take the filter information from your request DTO and use them in your data query.
// When using for example EntityFramework.Core to fetch your data from a DB, the most convenient approach would
// be to use System.Linq.Dynamic.Core package and simply feed the filters to your IQueryable instance:
public async Task<PagedResponse<Model>> GetModels(YourRequestDto filter)
{
	var baseQuery = AppDbContext.Models.AsNoTracking();
	var combinedFilter = String.Join(" or ", filter.FilterStrings) // of course you can also use " and " to combine individual filters
	var filteredQuery = baseQuery.Where(combinedFilter); // This line requires System.Linq.Dynamic.Core to work

	// perform further steps on your db entities (e.g. sorting, pagination, projection etc.)
	// ...
	return serviceResponse;
}

Checklist:

  • The PR is submitted to the correct branch (dev).
  • My code follows the code style of this project.
  • I've added relevant tests.

@TobiasBreuer
Copy link
Author

@tjscience I changed the code in DataGridAggregationExample because tests are failing on my machine. DataTime.Parse is pretty depending on your UI culture (mine is a mixture of EN-GB and DE-DE) which expects day/month/year. However the tests are using month/day/year. To make it independent on the executing system environment, I therefore specified the format explicitly.

@TobiasBreuer
Copy link
Author

Functionality wise, this PR is pretty much everything required.
If you want me to change something, let me know ;-)

@tjscience
Copy link
Owner

@tjscience I changed the code in DataGridAggregationExample because tests are failing on my machine. DataTime.Parse is pretty depending on your UI culture (mine is a mixture of EN-GB and DE-DE) which expects day/month/year. However the tests are using month/day/year. To make it independent on the executing system environment, I therefore specified the format explicitly.

Hi @TobiasBreuer, yes this was already fixed in a separate branch and has been merged into the base repo. I hadn't merged that into my dev yet though. No worries, I will fix that up when I merge your changes. I will have a look at everything as soon as I can. Thanks!

@tjscience tjscience merged commit c34ad3b into tjscience:dev Mar 10, 2022
@TobiasBreuer TobiasBreuer deleted the feature/enhance-filterdefinitions branch March 10, 2022 13:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants