From 15850b54dd2fd94e6bb6686e6aadbfacb64d4c29 Mon Sep 17 00:00:00 2001 From: Sean Prashad Date: Fri, 5 Jun 2020 18:14:47 -0400 Subject: [PATCH] Enable sorting question list via Companies The `Difficulty` filter is now hard-coded, as to avoid running into edge cases using preFilteredRows/filteredRows (see https://github.com/tannerlinsley/react-table/blob/master/docs/api/useFilters.md#column-properties). All filters have been refactored out to a seperate file (filters.js), to reduce code clutter in the Table component. The question list is now sorted by difficulty by default when being exported from src/data/index.js. Fixes #13 --- src/components/Table/filters.js | 63 ++++++++++++++++++++++++++ src/components/Table/index.js | 78 ++++++-------------------------- src/components/Table/styles.scss | 16 ++++--- src/data/index.js | 8 +++- 4 files changed, 93 insertions(+), 72 deletions(-) create mode 100644 src/components/Table/filters.js diff --git a/src/components/Table/filters.js b/src/components/Table/filters.js new file mode 100644 index 00000000..8be4b586 --- /dev/null +++ b/src/components/Table/filters.js @@ -0,0 +1,63 @@ +import React from 'react'; + +function CreateDropDownListHelper(options, filterValue, setFilter) { + return ( + + ); +} + +export function DefaultColumnFilter({ + column: { filterValue, preFilteredRows, setFilter, id }, +}) { + const count = preFilteredRows.length; + + return ( + { + setFilter(e.target.value || ''); + }} + placeholder={`Search ${count} questions`} + /> + ); +} + +export function SelectDifficultyColumnFilter({ + column: { filterValue, setFilter }, +}) { + const options = ['Easy', 'Medium', 'Hard']; + + return CreateDropDownListHelper(options, filterValue, setFilter); +} + +export function SelectColumnFilter({ + column: { filterValue, setFilter, preFilteredRows, id }, +}) { + const options = React.useMemo(() => { + const set = new Set(); + + preFilteredRows.forEach(row => { + const values = String(row.values[id]).split(','); + + values.forEach(value => { + set.add(value); + }); + }); + + return [...set.values()].sort(); + }, [id, preFilteredRows]); + + return CreateDropDownListHelper(options, filterValue, setFilter); +} diff --git a/src/components/Table/index.js b/src/components/Table/index.js index 6446b2df..fa32432d 100644 --- a/src/components/Table/index.js +++ b/src/components/Table/index.js @@ -9,30 +9,30 @@ import { import ReactTooltip from 'react-tooltip'; import { useTable, useFilters, useSortBy } from 'react-table'; import { FaQuestionCircle, FaLock } from 'react-icons/fa'; +import { + DefaultColumnFilter, + SelectDifficultyColumnFilter, + SelectColumnFilter, +} from './filters'; import { Event } from '../Shared/Tracking'; -import questionList from '../../data'; +import questions from '../../data'; import './styles.scss'; const images = require.context('../../icons', true); -const sortByObject = { Easy: 0, Medium: 1, Hard: 2 }; -questionList.sort( - (a, b) => sortByObject[a.difficulty] - sortByObject[b.difficulty], -); - const Table = () => { const [checked, setChecked] = useState( JSON.parse(localStorage.getItem('checked')) || - new Array(questionList.length).fill(false), + new Array(questions.length).fill(false), ); useEffect(() => { window.localStorage.setItem('checked', JSON.stringify(checked)); }, [checked]); - const data = React.useMemo(() => questionList, []); + const data = React.useMemo(() => questions, []); const defaultColumn = React.useMemo( () => ({ @@ -73,8 +73,8 @@ const Table = () => { return ( {cellInfo.row.original.premium ? ( - - {' '} + + ) : ( '' @@ -123,7 +123,7 @@ const Table = () => { {cellInfo.row.original.difficulty} ), - Filter: SelectColumnFilter, + Filter: SelectDifficultyColumnFilter, }, { Header: () => { @@ -152,7 +152,7 @@ const Table = () => { return {companies}; }, - disableFilters: true, + Filter: SelectColumnFilter, }, ], }, @@ -161,56 +161,6 @@ const Table = () => { [], ); - function DefaultColumnFilter({ - column: { filterValue, preFilteredRows, setFilter }, - }) { - const count = preFilteredRows.length; - - return ( - { - setFilter(e.target.value || undefined); // Set undefined to remove the filter entirely - }} - placeholder={`Search ${count} questions...`} - /> - ); - } - - function SelectColumnFilter({ - column: { filterValue, setFilter, preFilteredRows, id }, - }) { - const options = React.useMemo(() => { - const options = new Set(); - - preFilteredRows.forEach(row => { - options.add(row.values[id]); - }); - - if (id === 'difficulty') { - return [...options.values()]; - } - - return [...options.values()].sort(); - }, [id, preFilteredRows]); - - return ( - - ); - } - const { getTableProps, getTableBodyProps, @@ -233,10 +183,10 @@ const Table = () => { return ( - + {headerGroups.map(headerGroup => ( - + {headerGroup.headers.map(column => ( {column.render('Header')} diff --git a/src/components/Table/styles.scss b/src/components/Table/styles.scss index 4d005ea2..a25a9306 100644 --- a/src/components/Table/styles.scss +++ b/src/components/Table/styles.scss @@ -3,14 +3,16 @@ justify-content: center; } - thead > tr:first-child { - display: none; - } + thead { + > tr:first-child { + display: none; + } - tr.sticky th { - background: white; - position: sticky; - top: 0; + > tr th { + background: white; + position: sticky; + top: 0; + } } .nav-link { diff --git a/src/data/index.js b/src/data/index.js index 7848af68..54962342 100644 --- a/src/data/index.js +++ b/src/data/index.js @@ -1,4 +1,4 @@ -export default [ +const questions = [ { id: 0, name: 'Contains Duplicate', @@ -2056,3 +2056,9 @@ export default [ companies: ['Oracle'], }, ]; + +const sortBy = { Easy: 0, Medium: 1, Hard: 2 }; + +export default questions.sort( + (a, b) => sortBy[a.difficulty] - sortBy[b.difficulty], +);