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

[DataGrid] Add is any of filter operator #2874

Merged
merged 66 commits into from Jan 17, 2022

Conversation

alexfauquette
Copy link
Member

@alexfauquette alexfauquette commented Oct 14, 2021

Closes #2437

The idea is to add the "is one of" filtering condition.

For now, filtering has been imagined as containing a unique value. I'm modifying the pipeline to allow an array of values.

  • Column Type to support
    • text
    • number
    • date (relevant?)
    • datetime-local (relevant?)
    • singleSelect
  • tests
  • doc

To test the is any of:
https://deploy-preview-2874--material-ui-x.netlify.app/components/data-grid/filtering/#predefined-filters

The documentation about how to create custom filters operators with multiple values:
https://deploy-preview-2874--material-ui-x.netlify.app/components/data-grid/filtering/#multiple-values-operator

@flaviendelangle
Copy link
Member

flaviendelangle commented Oct 15, 2021

Is their an issue that was asking for this feature ? If so, can you link it in the description of the PR ?

@alexfauquette
Copy link
Member Author

The idea is to add a field isArrayValue in FilterItem, such that dev can choose if its filter will be based on a single value or an array of values.

@alexfauquette alexfauquette self-assigned this Oct 19, 2021
@@ -48,8 +48,9 @@ GridColumnsMenuItem.propTypes = {
filterOperators: PropTypes.arrayOf(
PropTypes.shape({
getApplyFilterFn: PropTypes.func.isRequired,
InputComponent: PropTypes.elementType,
InputComponent: PropTypes.func,
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I do not understand Why InputComponent is now considered as a function. Its type is made of the union of two JSXElements.

InputComponent?:
    | React.JSXElementConstructor<GridFilterInputValueProps>
    | React.JSXElementConstructor<
        GridFilterInputMultipleValueProps &
          Omit<AutocompleteProps<any[], true, false, true>, 'options' | 'renderInput'>
      >;

(in gridFilterOperator.ts)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

https://github.com/merceyz/typescript-to-proptypes/blob/a184bc439be86749436cd5eb05e99f29199f9055/src/generator.ts#L264

I do not see any obvious problem in their code
Maybe you can link it locally and have a look if this is a problem in JSDoc (in which case I would not go fix it if I were you) or just a small bug in Typescript-to-Proptypes.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it is because the two JSX elements have different props and then are considered as different objects. So it provides the common property: they are both function

@alexfauquette
Copy link
Member Author

Because Autocomplete distinguishes onChange and onInputChange, the filtering is not applied while the user is typing. Filters are applied each time the value change (Chip added or removed)

Do you have an opinion on the expected behavior? Should the filter be applied or not when the user is typing?

@flaviendelangle
Copy link
Member

Do you have an opinion on the expected behavior? Should the filter be applied or not when the user is typing?

I think it should not, for performances reason.

@DanailH DanailH changed the title [DataGrid] allows to us "in one of" filter operator [DataGrid] Allows to us "in one of" filter operator Oct 22, 2021
@DanailH DanailH changed the title [DataGrid] Allows to us "in one of" filter operator [DataGrid] Add 'in one of' filter operator Oct 22, 2021
@DanailH DanailH changed the title [DataGrid] Add 'in one of' filter operator [DataGrid] Add in one of filter operator Oct 22, 2021
@DanailH DanailH added component: data grid This is the name of the generic UI component, not the React module! new feature New feature or request labels Oct 22, 2021
@github-actions github-actions bot added the PR: out-of-date The pull request has merge conflicts and can't be merged label Oct 22, 2021
@github-actions
Copy link

This pull request has conflicts, please resolve those before we can evaluate the pull request.

@alexfauquette alexfauquette changed the title [DataGrid] Add in one of filter operator [DataGrid] Add is one of filter operator Oct 25, 2021
@flaviendelangle
Copy link
Member

For date and datetime, it could be nice to add a range operator later.
But I agree that the in one of is not relevant for datetime and probably not for date (at least we can wait for feedbacks)

@alexfauquette
Copy link
Member Author

On the same idea, we will be able to add a "is between" for numbers

@alexfauquette
Copy link
Member Author

To be consistent with the other singleSelect, the item.value only contains the value, such that the valueParser gets the same input format. And the local state of the component contains the objects if valueOptions is made of objects.

@m4theushw
Copy link
Member

@alexfauquette Then the alternative seems to be to map the values provided to the chips, so it's always an object instead of a value.

@alexfauquette
Copy link
Member Author

@m4theushw I've been unclear in my previous message. The formating problem is solved. I was briefly describing how I change the state management such that Chip formatting works.

So with the new commits, we have:

  • value provided to the filterModel: an array of value
  • value provided to the autoComplete: an array of object


if (itemValue.length !== item.value.length) {
// remove filtered values
applyValue({ ...item, value: parsedCurrentValueOptions });
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is causing an infinite loop. Maybe we're missing a test case covering the selection of items to filter with a click, not only changing props.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, tests were made only on the operator "is", so I added similar ones on "isAnyOf" to verify if the values are cleaned when changing the column.

I also refactorized how value is sanitized. The AutoComplete requires to have coherent values with options, so I sanitize the value with a useMemo. Such that the sanitization is performed before rendering the AutoComplete component.

If sanitization removes some elements, the DataGrid state is updated by a dedicated hook.

I spend too much time on this little piece of code. I'm taking a break on it, and I come back tomorrow to check on the deployment if it is working as expected, or if bugs are remaining

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I played with filtering, no trivial bug was found this time

Copy link
Member

@m4theushw m4theushw left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well done! 👌

const id = useId();

const currentColumn = item.columnField ? apiRef.current.getColumn(item.columnField) : null;
const currentValueOptions = React.useMemo(() => {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about this name?

Suggested change
const currentValueOptions = React.useMemo(() => {
const resolvedValueOptions = React.useMemo(() => {

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, it will be more logic, since data are resolved from the apiRef. I've done the modification for the following namings:

  • resolvedColumn
  • resolvedValueOptions
  • resolvedFormattedValueOptions

@github-actions
Copy link

This pull request has conflicts, please resolve those before we can evaluate the pull request.

@github-actions github-actions bot added the PR: out-of-date The pull request has merge conflicts and can't be merged label Jan 10, 2022
@github-actions github-actions bot removed the PR: out-of-date The pull request has merge conflicts and can't be merged label Jan 10, 2022
@alexfauquette
Copy link
Member Author

I will wait for #3437 to adapt the documentation

@github-actions github-actions bot added the PR: out-of-date The pull request has merge conflicts and can't be merged label Jan 11, 2022
@github-actions
Copy link

This pull request has conflicts, please resolve those before we can evaluate the pull request.

@flaviendelangle
Copy link
Member

#3437 is merged, we can fix the conflicts and merge this one

@github-actions github-actions bot removed the PR: out-of-date The pull request has merge conflicts and can't be merged label Jan 14, 2022
@mui-bot
Copy link

mui-bot commented Jan 14, 2022

These are the results for the performance tests:

Test case Unit Min Max Median Mean σ
Filter 100k rows ms 135.1 240.2 190.1 182.74 36.875
Sort 100k rows ms 350.9 562.9 521.1 475.42 83.037
Select 100k rows ms 130.8 272.5 182.6 184.94 49.155
Deselect 100k rows ms 92.3 145.3 142.9 128.18 19.003

Generated by 🚫 dangerJS against c452f57

@alexfauquette alexfauquette merged commit 0fc9429 into mui:master Jan 17, 2022
@alexfauquette alexfauquette deleted the new-filter-operator branch January 17, 2022 11:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
component: data grid This is the name of the generic UI component, not the React module! new feature New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[DataGrid] Add operator to filter for rows that contain any of the specified values
5 participants