-
-
Notifications
You must be signed in to change notification settings - Fork 3.6k
fix(table-core): avoid parent lookup re-entrancy #6441
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -80,6 +80,55 @@ const rowNames = (rows: Array<{ original: { name: string } }>) => | |
| rows.map((row) => row.original.name) | ||
|
|
||
| describe('createFilteredRowModel', () => { | ||
| it('allows a filter function to inspect structural parent rows', () => { | ||
| const parentAwareFilter: FilterFn<typeof features, NestedRow> = ( | ||
| row, | ||
| columnId, | ||
| filterValue, | ||
| ) => { | ||
| const parent = row.getParentRow() | ||
| return [row, parent] | ||
| .filter((candidate) => candidate !== undefined) | ||
| .some((candidate) => | ||
| String(candidate.getValue(columnId)) | ||
| .toLowerCase() | ||
| .includes(String(filterValue).toLowerCase()), | ||
| ) | ||
| } | ||
| const table = constructTable<typeof features, NestedRow>({ | ||
| features, | ||
| columns: [ | ||
| { | ||
| accessorKey: 'name', | ||
| id: 'name', | ||
| filterFn: parentAwareFilter, | ||
| }, | ||
| ], | ||
| data: [ | ||
| { name: 'parent', subRows: [{ name: 'child' }] }, | ||
| { name: 'other', subRows: [{ name: 'nested' }] }, | ||
| ], | ||
| getSubRows: (row) => row.subRows, | ||
| initialState: { | ||
| columnFilters: [{ id: 'name', value: 'parent' }], | ||
| }, | ||
| }) | ||
|
|
||
| expect(() => table.getFilteredRowModel()).not.toThrow() | ||
| expect(rowNames(table.getFilteredRowModel().flatRows).sort()).toEqual([ | ||
| 'child', | ||
| 'parent', | ||
| ]) | ||
|
|
||
| table.setColumnFilters([{ id: 'name', value: 'other' }]) | ||
|
|
||
| expect(() => table.getFilteredRowModel()).not.toThrow() | ||
| expect(rowNames(table.getFilteredRowModel().flatRows).sort()).toEqual([ | ||
| 'nested', | ||
| 'other', | ||
| ]) | ||
|
Comment on lines
+107
to
+129
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win Cover descendant matches across multiple nesting levels. The fixture only has one child level, and both filter values match parents. Add a grandchild plus a descendant-matching filter case, asserting its ancestor family is retained; this validates recursive parent lookup and the linked issue’s multi-level requirement. 🤖 Prompt for AI Agents |
||
| }) | ||
|
|
||
| it('should assign display indexes in filtered row order', () => { | ||
| const table = constructTable<typeof features, TestRow>({ | ||
| features, | ||
|
|
||
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.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
Preserve empty-string row IDs.
Line 203 treats
''as no parent, so customgetRowIdimplementations using an empty-string ID cannot resolve their children’s parent. Check specifically forundefined.Proposed fix
📝 Committable suggestion
🤖 Prompt for AI Agents