Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enable sorting question list via Companies #21

Merged
merged 1 commit into from
Jun 5, 2020
Merged
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
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
  • Loading branch information
Sean Prashad authored and Sean Prashad committed Jun 5, 2020
commit 15850b54dd2fd94e6bb6686e6aadbfacb64d4c29
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],
);