From c3de553b18e84c1195c6f03ec8f7e1782ba1753a Mon Sep 17 00:00:00 2001 From: Hina Shah Date: Tue, 18 Mar 2025 10:01:25 -0400 Subject: [PATCH] Adding filtering to the each column of the results table --- .../answer/resultsTable/ResultsTable.jsx | 47 ++++++++++++++++++- .../answer/resultsTable/resultsTable.css | 7 +++ src/utils/results.js | 14 ++++-- 3 files changed, 62 insertions(+), 6 deletions(-) diff --git a/src/pages/answer/resultsTable/ResultsTable.jsx b/src/pages/answer/resultsTable/ResultsTable.jsx index 6c0d8a12..6edb77c6 100644 --- a/src/pages/answer/resultsTable/ResultsTable.jsx +++ b/src/pages/answer/resultsTable/ResultsTable.jsx @@ -1,5 +1,7 @@ import React, { useMemo } from 'react'; -import { useTable, usePagination, useSortBy } from 'react-table'; +import { + useTable, usePagination, useSortBy, useFilters, +} from 'react-table'; import Paper from '@material-ui/core/Paper'; import TableContainer from '@material-ui/core/TableContainer'; @@ -23,6 +25,46 @@ import './resultsTable.css'; export default function ResultsTable({ answerStore }) { const columns = useMemo(() => answerStore.tableHeaders, [answerStore.tableHeaders]); const data = useMemo(() => answerStore.message.results, [answerStore.message]); + + // This is a custom filter UI for selecting + // a unique option from a list + function SelectColumnFilterFn({ + column: { + filterValue, setFilter, preFilteredRows, id, + }, + }) { + // Calculate the options for filtering + // using the preFilteredRows + const options = useMemo(() => { + const o = new Set(); + preFilteredRows.forEach((row) => { + o.add(row.values[id] ? row.values[id] : null); + }); + return [...o.values()]; + }, [id, preFilteredRows]); + + // Render a multi-select box + return ( + + ); + } + + // Let's set up our default Filter UI + const defaultColumn = useMemo(() => ({ Filter: SelectColumnFilterFn }), []); + const { getTableProps, getTableBodyProps, headerGroups, @@ -35,6 +77,7 @@ export default function ResultsTable({ answerStore }) { { columns, data, + defaultColumn, initialState: { pageIndex: 0, pageSize: 10, @@ -46,6 +89,7 @@ export default function ResultsTable({ answerStore }) { ], }, }, + useFilters, useSortBy, usePagination, ); @@ -85,6 +129,7 @@ export default function ResultsTable({ answerStore }) { {column.render('Header')} )} +
{column.canFilter ? column.render('Filter') : null}
))} diff --git a/src/pages/answer/resultsTable/resultsTable.css b/src/pages/answer/resultsTable/resultsTable.css index a6f5808b..49e1ed1f 100644 --- a/src/pages/answer/resultsTable/resultsTable.css +++ b/src/pages/answer/resultsTable/resultsTable.css @@ -14,6 +14,13 @@ border: 1px solid lightgray; border-collapse: collapse; } + +.resultsFilterSelect { + max-width: 50%; + width: 100%; /* Ensures responsiveness */ + padding: 5px; +} + /* override table hover colors */ .MuiTableRow-root.Mui-selected { background-color: rgba(13, 0, 30, 0.08); diff --git a/src/utils/results.js b/src/utils/results.js index 99dc58b5..fba562c7 100644 --- a/src/utils/results.js +++ b/src/utils/results.js @@ -121,16 +121,19 @@ function makeTableHeaders(message, colorMap) { Header: `${headerText} (${id})`, color: backgroundColor, id, - accessor: (row) => row.node_bindings[id], - Cell: ({ value }) => { - if (value.length > 1) { + accessor: (row) => { + const nodeBinding = row.node_bindings[id]; + if (!nodeBinding || nodeBinding.length === 0) return ''; + if (nodeBinding.length > 1) { // this is a set - return `Set of ${stringUtils.displayCategory(qgNode.categories)} [${value.length}]`; + return `Set of ${stringUtils.displayCategory(qgNode.categories)} [${nodeBinding.length}]`; } - return knowledge_graph.nodes[value[0].id].name || value[0].id; + return knowledge_graph.nodes[nodeBinding[0].id].name || nodeBinding[0].id; }, + Cell: ({ value }) => value || 'Unknown', disableSortBy: true, width, + filter: 'equals', }; }); if (results.length && results[0].score) { @@ -140,6 +143,7 @@ function makeTableHeaders(message, colorMap) { accessor: (row) => Math.round(row.score * 1000) / 1000, width: 30, sortDescFirst: true, + disableFilters: true, }; headerColumns.push(scoreColumn); }