Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ function filterRowModelFromLeafs<
Partial<Row_ColumnFiltering<TFeatures, TData>> = []

// Filter from children up first
for (let row of rowsToFilter) {
for (const row of rowsToFilter) {
const newRow = constructRow(
table,
row.id,
Expand All @@ -66,36 +66,25 @@ function filterRowModelFromLeafs<

if (row.subRows.length && depth < maxDepth) {
newRow.subRows = recurseFilterRows(row.subRows, depth + 1)
row = newRow

if (filterRow(row) && !newRow.subRows.length) {
filteredRows.push(row)
newFilteredRowsById[row.id] = row
newFilteredFlatRows.push(row)
continue
}

if (filterRow(row) || newRow.subRows.length) {
filteredRows.push(row)
newFilteredRowsById[row.id] = row
newFilteredFlatRows.push(row)
continue
if (filterRow(newRow) || newRow.subRows.length) {
filteredRows.push(newRow)
}
} else {
row = newRow
if (filterRow(row)) {
filteredRows.push(row)
newFilteredRowsById[row.id] = row
newFilteredFlatRows.push(row)
if (filterRow(newRow)) {
filteredRows.push(newRow)
}
}
}

return filteredRows
}

const rows = recurseFilterRows(rowsToFilter)
addSubRowsToFlatArrays(rows, newFilteredFlatRows, newFilteredRowsById)

return {
rows: recurseFilterRows(rowsToFilter),
rows,
flatRows: newFilteredFlatRows,
rowsById: newFilteredRowsById,
}
Expand Down Expand Up @@ -123,7 +112,7 @@ function filterRowModelFromRoot<
const filteredRows: Array<Row<TFeatures, TData>> = []

// Apply the filter to any subRows
for (let row of rowsToFilter) {
for (const row of rowsToFilter) {
const pass = filterRow(row)

if (pass) {
Expand All @@ -136,26 +125,35 @@ function filterRowModelFromRoot<
row.depth,
undefined,
row.parentId,
)
) as Row<TFeatures, TData> &
Partial<Row_ColumnFiltering<TFeatures, TData>>
newRow.columnFilters = (
row as Row<TFeatures, TData> &
Partial<Row_ColumnFiltering<TFeatures, TData>>
).columnFilters

filteredRows.push(newRow)
newFilteredFlatRows.push(newRow)
newFilteredRowsById[newRow.id] = newRow

newRow.subRows = recurseFilterRows(row.subRows, depth + 1)
row = newRow
}
} else {
filteredRows.push(row)
newFilteredFlatRows.push(row)
newFilteredRowsById[row.id] = row

filteredRows.push(row)
newFilteredFlatRows.push(row)
newFilteredRowsById[row.id] = row

// When maxLeafRowFilterDepth stops the recursion, the kept row's
// subtree stays visible through row.subRows, so those descendants
// must still enter flatRows and rowsById to keep the flat
// representation (and anything derived from it, like facet counts)
// consistent with the visible tree
if (row.subRows.length && depth >= maxDepth) {
addSubRowsToFlatArrays(
row.subRows,
newFilteredFlatRows,
newFilteredRowsById,
)
// When maxLeafRowFilterDepth stops the recursion, the kept row's
// subtree stays visible through row.subRows, so those descendants
// must still enter flatRows and rowsById to keep the flat
// representation (and anything derived from it, like facet counts)
// consistent with the visible tree
if (row.subRows.length && depth >= maxDepth) {
addSubRowsToFlatArrays(
row.subRows,
newFilteredFlatRows,
newFilteredRowsById,
)
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -188,11 +188,11 @@ describe('createFilteredRowModel', () => {
expect(rowNames(model.flatRows)).not.toContain('keep-b1')
})

it('should include cloned rows and exclude dropped rows in flatRows and rowsById', () => {
it('should include cloned rows and exclude dropped rows in flatRows and rowsById in pre-order', () => {
const table = makeNestedTable()
const model = table.getFilteredRowModel()

expect(rowNames(model.flatRows).sort()).toEqual([
expect(rowNames(model.flatRows)).toEqual([
'keep-a',
'keep-a1',
'keep-c',
Expand Down Expand Up @@ -222,6 +222,20 @@ describe('createFilteredRowModel', () => {
expect(rowNames(dropB.subRows)).toEqual(['keep-b1'])
})

it('should flatten rows in pre-order with each parent ahead of its sub-rows', () => {
const table = makeNestedTable({ filterFromLeafRows: true })
const { flatRows } = table.getFilteredRowModel()

expect(rowNames(flatRows)).toEqual([
'keep-a',
'keep-a1',
'drop-b',
'keep-b1',
'keep-c',
'keep-d',
])
})

it('should keep a matching parent that has no matching children', () => {
const table = makeNestedTable({ filterFromLeafRows: true })
const { rows } = table.getFilteredRowModel()
Expand Down Expand Up @@ -254,11 +268,7 @@ describe('createFilteredRowModel', () => {
expect(rowNames(rows)).toEqual(['drop-x'])
expect(rowNames(rows[0]!.subRows)).toEqual(['drop-x1'])
expect(rowNames(rows[0]!.subRows[0]!.subRows)).toEqual(['keep-x1a'])
expect(rowNames(flatRows).sort()).toEqual([
'drop-x',
'drop-x1',
'keep-x1a',
])
expect(rowNames(flatRows)).toEqual(['drop-x', 'drop-x1', 'keep-x1a'])
})

it('should prune matching subRows from a matching parent while filtering', () => {
Expand Down Expand Up @@ -324,13 +334,12 @@ describe('createFilteredRowModel', () => {
const model = table.getFilteredRowModel()

// Depth-1 children are still filtered (drop-a2 removed), while the
// depth-2 subtree of keep-a1 is kept as-is and joins flatRows. The
// pre-existing flatRows order pushes recursed children before their
// parent.
// depth-2 subtree of keep-a1 is kept as-is and joins flatRows in
// pre-order traversal (parent before children).
expect(rowNames(model.flatRows)).toEqual([
'keep-a',
'keep-a1',
'drop-a1a',
'keep-a',
'keep-c',
'keep-d',
])
Expand Down Expand Up @@ -716,4 +725,66 @@ describe('createFilteredRowModel', () => {
expect(table.getFilteredRowModel()).toBe(table.getPreFilteredRowModel())
})
})

describe('pre-order flatRows traversal', () => {
const complexNestedData: Array<NestedRow> = [
{
name: 'parent-1',
subRows: [
{
name: 'child-1.1',
subRows: [
{ name: 'grandchild-1.1.1' },
{ name: 'grandchild-1.1.2' },
],
},
{ name: 'child-1.2' },
],
},
{
name: 'parent-2',
subRows: [{ name: 'child-2.1' }],
},
]

it('flattens rows depth-first with each parent preceding its sub-rows (root filtering)', () => {
const table = constructTable<typeof features, NestedRow>({
features,
columns: nestedColumns,
data: complexNestedData,
getSubRows: (row) => row.subRows,
initialState: {
columnFilters: [{ id: 'name', value: '1' }],
},
})

expect(rowNames(table.getFilteredRowModel().flatRows)).toEqual([
'parent-1',
'child-1.1',
'grandchild-1.1.1',
'grandchild-1.1.2',
'child-1.2',
])
})

it('flattens rows depth-first with each parent preceding its sub-rows (leaf filtering)', () => {
const table = constructTable<typeof features, NestedRow>({
features,
columns: nestedColumns,
data: complexNestedData,
getSubRows: (row) => row.subRows,
filterFromLeafRows: true,
initialState: {
columnFilters: [{ id: 'name', value: '.2' }],
},
})

expect(rowNames(table.getFilteredRowModel().flatRows)).toEqual([
'parent-1',
'child-1.1',
'grandchild-1.1.2',
'child-1.2',
])
})
})
})