-
Notifications
You must be signed in to change notification settings - Fork 57
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(autgrid): Add custom filtering option to columns #1911
Conversation
Codecov ReportAttention:
Additional details and impacted files@@ Coverage Diff @@
## main #1911 +/- ##
==========================================
- Coverage 95.27% 95.24% -0.04%
==========================================
Files 52 52
Lines 3449 3469 +20
Branches 503 514 +11
==========================================
+ Hits 3286 3304 +18
+ Misses 136 134 -2
- Partials 27 31 +4
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. |
@@ -11,6 +11,8 @@ | |||
public class AndFilter extends Filter { | |||
private List<Filter> children; | |||
|
|||
private String key; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems we only need this internally in order to be able to replace the correct filter instance in the root filter of the AutoGrid
. If that is the case then adding this as a required property to the public API isn't a good solution (also a breaking change). I think it will also be confusing to developers what this key is and why they have to manage it.
I think we could manage this key internally / automatically. We could add a key
parameter to AutoGrid
's setPropertyFilter
. The key could be the column's key
, or an incremental number stored in a ref. When exposing the setPropertyFilter
to the header filters, we do not pass the original function, but a wrapper function that automatically sets the key:
export function InternalHeaderFilterRenderer({ original }: HeaderRendererProps): JSX.Element | null {
const {
setPropertyFilter: setPropertyFilterOriginal,
headerFilterRenderer: HeaderFilterRenderer,
filterKey, // Would be determined somehow when rendering the context
} = useContext(ColumnContext)!;
function setPropertyFilter(filter: FilterUnion) {
setPropertyFilterOriginal(filterKey, filter);
}
return <HeaderFilterRenderer original={original} setPropertyFilter={setPropertyFilter} />;
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agree and I implemented your suggested changes.
Only code will use the key
property for custom columns and property.name
for model-type columns as identifiers for filter management.
@@ -105,15 +108,31 @@ export function getColumnOptions( | |||
customColumnOptions: ColumnOptions | undefined, | |||
): ColumnOptions { | |||
const typeColumnOptions = getTypeColumnOptions(propertyInfo); | |||
const finalHeaderRenderer = | |||
customColumnOptions?.filterable === false ? NoHeaderFilter : typeColumnOptions.headerRenderer; | |||
const HeaderFilterRenderer = |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: IMO writing this in upper-case creates visual noise for no real benefit. It could just be headerFilterRenderer
and then be cleanly applied in the object below with a shorthand assignment.
} | ||
return columnOptions; | ||
} | ||
|
||
export function InternalHeaderFilterRenderer({ original }: HeaderRendererProps): JSX.Element | null { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think these wrappers would a better fit for header-filter.tsx
.
Since they effectively do the same, maybe combine them into one:
export function InternalHeaderFilterRenderer({ original }: HeaderRendererProps): JSX.Element | null {
const { setPropertyFilter, headerFilterRenderer: HeaderFilterRenderer } = (useContext(ColumnContext) ?? useContext(CustomColumnContext))!;
return <HeaderFilterRenderer original={original} setPropertyFilter={setPropertyFilter} />;
}
The name could also be improved to clarify its intent.
if (!columnOptions.headerRenderer) { | ||
console.error(`No header renderer defined for column ${propertyInfo.name}`); | ||
if (!columnOptions.headerFilterRenderer) { | ||
console.error(`No filter renderer defined for column ${propertyInfo.name}`); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this serve a purpose? Should we just use NoHeaderFilter
as a fallback?
if (HeaderFilterRenderer) { | ||
return <HeaderFilterRenderer original={original} setPropertyFilter={setPropertyFilter} />; | ||
} | ||
return null; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can solve the missing code coverage here by making headerFilterRenderer
required, and using NoHeaderFilter
if no custom renderer is specified.
const { key } = column; | ||
const { header, headerRenderer: HeaderRenderer } = column.props; | ||
const customOptions = options.columnOptions?.[key!]; | ||
const { header: customHeader, headerRenderer: CustomHeaderRenderer, headerFilterRenderer } = customOptions ?? {}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: Likewise, the uppercase here doesn't provide any benefit.
@@ -186,7 +219,7 @@ function addCustomColumns(columns: JSX.Element[], options: ColumnConfigurationOp | |||
|
|||
function useColumns( | |||
properties: PropertyInfo[], | |||
setPropertyFilter: (propertyFilter: PropertyStringFilter) => void, | |||
setPropertyFilter: (filter: PropertyStringFilter) => void, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't this use FilterUnion
?
} | ||
return null; | ||
} | ||
const isEmpty = (filter: FilterUnion): boolean => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like this could use more test coverage. Maybe consider extracting this into a utility and testing it separately.
/** | ||
* Custom renderer for the title/sorter in the header. | ||
*/ | ||
headerRenderer?: ComponentType<HeaderRendererProps>; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Doesn't look like this is needed, ColumnOptions
already has headerRenderer
from GridColumnProps
.
* Allows to set custom filter for a property. This is used by the header filter components. | ||
* @param filter - The filter to set in the filter list. | ||
*/ | ||
setPropertyFilter(filter: FilterUnion): void; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As this accepts a filter union, it can do more than filtering single properties. Maybe we should rename this to setFilter
. Internally we could use setColumnFilter
as that's what it basically does now.
Fixes #1608, #1501 *Provide headerFilterRender for users as a new property in columnOptions *Split headerRenderer and headerFilterRenderer to solve consistency issue with headerRenderer being responsible for two places. *Provide setPropertyFilter function to headerFilterRenderer as a property in columnOptions *Add identifier to andFilter and orFilter (key) for controlling (delete/replace/add) filter list *Change setPropertyFilter to accept any Filter not only StringPropertyFilter *Enable adding headerFilterRenderer to custom columns *Enable setting headerRenderer from columnOptions as primary source (overwriting default) *Provide types to users: ColumnOptions, HeaderFilterRendererProps
…lter working Rename InternalHeaderFilterRenderer to HeaderFilterWrapper
dad84f9
to
7be51df
Compare
Quality Gate passedThe SonarCloud Quality Gate passed, but some issues were introduced. 3 New issues |
Fixes #1608, #1501