import { createRow } from '../core/row' import { Row, RowModel, Table, RowData } from '../types' export function filterRows( rows: Row[], filterRowImpl: (row: Row) => any, table: Table ) { if (table.options.filterFromLeafRows) { return filterRowModelFromLeafs(rows, filterRowImpl, table) } return filterRowModelFromRoot(rows, filterRowImpl, table) } export function filterRowModelFromLeafs( rowsToFilter: Row[], filterRow: (row: Row) => Row[], table: Table ): RowModel { const newFilteredFlatRows: Row[] = [] const newFilteredRowsById: Record> = {} const maxDepth = table.options.maxLeafRowFilterDepth ?? 100 const recurseFilterRows = (rowsToFilter: Row[], depth = 0) => { const rows: Row[] = [] // Filter from children up first for (let i = 0; i < rowsToFilter.length; i++) { let row = rowsToFilter[i]! const newRow = createRow( table, row.id, row.original, row.index, row.depth ) newRow.columnFilters = row.columnFilters if (row.subRows?.length && depth < maxDepth) { newRow.subRows = recurseFilterRows(row.subRows, depth + 1) row = newRow if (filterRow(row) && !newRow.subRows.length) { rows.push(row) newFilteredRowsById[row.id] = row newFilteredRowsById[i] = row continue } if (filterRow(row) || newRow.subRows.length) { rows.push(row) newFilteredRowsById[row.id] = row newFilteredRowsById[i] = row continue } } else { row = newRow if (filterRow(row)) { rows.push(row) newFilteredRowsById[row.id] = row newFilteredRowsById[i] = row } } } return rows } return { rows: recurseFilterRows(rowsToFilter), flatRows: newFilteredFlatRows, rowsById: newFilteredRowsById, } } export function filterRowModelFromRoot( rowsToFilter: Row[], filterRow: (row: Row) => any, table: Table ): RowModel { const newFilteredFlatRows: Row[] = [] const newFilteredRowsById: Record> = {} const maxDepth = table.options.maxLeafRowFilterDepth ?? 100 // Filters top level and nested rows const recurseFilterRows = (rowsToFilter: Row[], depth = 0) => { // Filter from parents downward first const rows: Row[] = [] // Apply the filter to any subRows for (let i = 0; i < rowsToFilter.length; i++) { let row = rowsToFilter[i]! const pass = filterRow(row) if (pass) { if (row.subRows?.length && depth < maxDepth) { const newRow = createRow( table, row.id, row.original, row.index, row.depth ) newRow.subRows = recurseFilterRows(row.subRows, depth + 1) row = newRow } rows.push(row) newFilteredFlatRows.push(row) newFilteredRowsById[row.id] = row } } return rows } return { rows: recurseFilterRows(rowsToFilter), flatRows: newFilteredFlatRows, rowsById: newFilteredRowsById, } }