Skip to content

Commit

Permalink
Enable sorting question list via Companies (#21)
Browse files Browse the repository at this point in the history
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
  • Loading branch information
Sean committed Jun 5, 2020
1 parent c39d65c commit 5423f06
Show file tree
Hide file tree
Showing 4 changed files with 93 additions and 72 deletions.
63 changes: 63 additions & 0 deletions src/components/Table/filters.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import React from 'react';

function CreateDropDownListHelper(options, filterValue, setFilter) {
return (
<select
value={filterValue}
onChange={e => {
setFilter(e.target.value || '');
}}
>
<option value="">All</option>
{options.map((option, idx) => (
<option key={idx} value={option}>
{option}
</option>
))}
</select>
);
}

export function DefaultColumnFilter({
column: { filterValue, preFilteredRows, setFilter, id },
}) {
const count = preFilteredRows.length;

return (
<input
value={filterValue || ''}
onChange={e => {
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);
}
78 changes: 14 additions & 64 deletions src/components/Table/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -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(
() => ({
Expand Down Expand Up @@ -73,8 +73,8 @@ const Table = () => {
return (
<span>
{cellInfo.row.original.premium ? (
<span data-tip="Requires leetcode premium">
<FaLock />{' '}
<span data-tip="Requires leetcode premium to view">
<FaLock />
</span>
) : (
''
Expand Down Expand Up @@ -123,7 +123,7 @@ const Table = () => {
{cellInfo.row.original.difficulty}
</Badge>
),
Filter: SelectColumnFilter,
Filter: SelectDifficultyColumnFilter,
},
{
Header: () => {
Expand Down Expand Up @@ -152,7 +152,7 @@ const Table = () => {

return <Row className="companies">{companies}</Row>;
},
disableFilters: true,
Filter: SelectColumnFilter,
},
],
},
Expand All @@ -161,56 +161,6 @@ const Table = () => {
[],
);

function DefaultColumnFilter({
column: { filterValue, preFilteredRows, setFilter },
}) {
const count = preFilteredRows.length;

return (
<input
value={filterValue || ''}
onChange={e => {
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 (
<select
value={filterValue}
onChange={e => {
setFilter(e.target.value || undefined);
}}
>
<option value="">All</option>
{options.map((option, i) => (
<option key={i} value={option}>
{option}
</option>
))}
</select>
);
}

const {
getTableProps,
getTableBodyProps,
Expand All @@ -233,10 +183,10 @@ const Table = () => {
return (
<Container className="table">
<ReactTooltip />
<ReactTable align="center" borderless striped hover {...getTableProps()}>
<ReactTable borderless striped hover {...getTableProps()}>
<thead>
{headerGroups.map(headerGroup => (
<tr className="sticky" {...headerGroup.getHeaderGroupProps()}>
<tr {...headerGroup.getHeaderGroupProps()}>
{headerGroup.headers.map(column => (
<th {...column.getHeaderProps()}>
{column.render('Header')}
Expand Down
16 changes: 9 additions & 7 deletions src/components/Table/styles.scss
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
8 changes: 7 additions & 1 deletion src/data/index.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
export default [
const questions = [
{
id: 0,
name: 'Contains Duplicate',
Expand Down Expand Up @@ -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],
);

0 comments on commit 5423f06

Please sign in to comment.