Improve pagination for search results

This commit is contained in:
Robbie Antenesse 2018-03-09 11:39:16 -07:00
parent 4c03b9c164
commit 6c21e4feec
4 changed files with 37 additions and 20 deletions

View File

@ -18,6 +18,7 @@ export class MainDisplay extends Component {
dictionaryInfo: PropTypes.object.isRequired, dictionaryInfo: PropTypes.object.isRequired,
wordsToDisplay: PropTypes.array.isRequired, wordsToDisplay: PropTypes.array.isRequired,
wordsAreFiltered: PropTypes.bool, wordsAreFiltered: PropTypes.bool,
wordsInCurrentList: PropTypes.number,
currentPage: PropTypes.number, currentPage: PropTypes.number,
itemsPerPage: PropTypes.number, itemsPerPage: PropTypes.number,
stats: PropTypes.object.isRequired, stats: PropTypes.object.isRequired,
@ -57,6 +58,7 @@ export class MainDisplay extends Component {
dictionaryInfo, dictionaryInfo,
wordsToDisplay, wordsToDisplay,
wordsAreFiltered, wordsAreFiltered,
wordsInCurrentList,
currentPage, currentPage,
itemsPerPage, itemsPerPage,
stats, stats,
@ -105,6 +107,14 @@ export class MainDisplay extends Component {
</div> </div>
)} )}
<Pagination
currentPage={ currentPage }
itemsPerPage={ itemsPerPage }
stats={ stats }
setPage={ setPage }
wordsInCurrentList={ wordsInCurrentList }
isTop />
<WordsList <WordsList
words={ wordsToDisplay } words={ wordsToDisplay }
adsEveryXWords={ 10 } adsEveryXWords={ 10 }
@ -114,7 +124,8 @@ export class MainDisplay extends Component {
currentPage={currentPage} currentPage={currentPage}
itemsPerPage={itemsPerPage} itemsPerPage={itemsPerPage}
stats={stats} stats={stats}
setPage={ setPage } /> setPage={setPage}
wordsInCurrentList={wordsInCurrentList} />
</RightColumn> </RightColumn>
</div> </div>

View File

@ -1,24 +1,25 @@
import Inferno from 'inferno'; import Inferno from 'inferno';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import './styles.scss';
export const Pagination = (props) => { export const Pagination = (props) => {
PropTypes.checkPropTypes({ PropTypes.checkPropTypes({
currentPage: PropTypes.number.isRequired, currentPage: PropTypes.number.isRequired,
itemsPerPage: PropTypes.number.isRequired, itemsPerPage: PropTypes.number.isRequired,
stats: PropTypes.object.isRequired, stats: PropTypes.object.isRequired,
setPage: PropTypes.func.isRequired, setPage: PropTypes.func.isRequired,
wordsInCurrentList: PropTypes.number,
isTop: PropTypes.bool,
}, props, 'prop', 'Pagination'); }, props, 'prop', 'Pagination');
const { currentPage, itemsPerPage, stats, setPage } = props; const { currentPage, itemsPerPage, stats, setPage, wordsInCurrentList, isTop } = props;
const totalWords = stats.hasOwnProperty('numberOfWords') if (wordsInCurrentList === null) {
? stats.numberOfWords.find(group => group.name === 'Total').value : null;
if (totalWords === null) {
return <div className="loader"></div>; return <div className="loader"></div>;
} }
const lastPage = Math.floor(totalWords / itemsPerPage); const lastPage = Math.floor(wordsInCurrentList / itemsPerPage);
const nextPage = currentPage + 1 > lastPage ? lastPage : currentPage + 1; const nextPage = currentPage + 1 > lastPage ? lastPage : currentPage + 1;
const prevPage = currentPage - 1 < 0 ? 0 : currentPage - 1; const prevPage = currentPage - 1 < 0 ? 0 : currentPage - 1;
@ -29,7 +30,7 @@ export const Pagination = (props) => {
} }
return ( return (
<nav className="pagination is-centered" role="navigation" aria-label="pagination"> <nav className={`pagination is-centered ${isTop ? 'is-top' : ''}`} role="navigation" aria-label="pagination">
<a className="pagination-previous" aria-label="Goto page 1" <a className="pagination-previous" aria-label="Goto page 1"
Disabled={currentPage === 0 ? 'disabled' : null} Disabled={currentPage === 0 ? 'disabled' : null}
onClick={() => changePage(prevPage)}> onClick={() => changePage(prevPage)}>

View File

@ -0,0 +1,3 @@
.pagination.is-top {
margin-bottom: 15px;
}

View File

@ -46,6 +46,7 @@ class App extends Component {
ignoreDiacritics: false, ignoreDiacritics: false,
filteredPartsOfSpeech: [...dictionary.partsOfSpeech, 'Uncategorized'], filteredPartsOfSpeech: [...dictionary.partsOfSpeech, 'Uncategorized'],
}, },
wordsInCurrentList: null,
} }
this.updater = new Updater(this, dictionary); this.updater = new Updater(this, dictionary);
@ -98,7 +99,7 @@ class App extends Component {
const partsOfSpeechForFilter = [...partsOfSpeech, 'Uncategorized']; const partsOfSpeechForFilter = [...partsOfSpeech, 'Uncategorized'];
const pageStart = currentPage * itemsPerPage; const pageStart = currentPage * itemsPerPage;
const pageEnd = pageStart + itemsPerPage; const pageEnd = pageStart + itemsPerPage;
let displayedWords; let displayedWords = words;
if (this.isUsingFilter) { if (this.isUsingFilter) {
const { const {
searchingIn, searchingIn,
@ -109,10 +110,7 @@ class App extends Component {
filteredPartsOfSpeech filteredPartsOfSpeech
} = searchConfig; } = searchConfig;
displayedWords = words.filter((word, index) => { displayedWords = displayedWords.filter((word, index) => {
if (index < pageStart || index >= pageEnd) {
return false;
}
const wordPartOfSpeech = word.partOfSpeech === '' ? 'Uncategorized' : word.partOfSpeech; const wordPartOfSpeech = word.partOfSpeech === '' ? 'Uncategorized' : word.partOfSpeech;
if (!filteredPartsOfSpeech.includes(wordPartOfSpeech)) { if (!filteredPartsOfSpeech.includes(wordPartOfSpeech)) {
return false; return false;
@ -168,18 +166,21 @@ class App extends Component {
} }
} }
}); });
} else { }
displayedWords = words.filter((word, index) => {
const wordsInCurrentList = displayedWords.length;
displayedWords = displayedWords.filter((word, index) => {
if (index < pageStart || index >= pageEnd) { if (index < pageStart || index >= pageEnd) {
return false; return false;
} }
return true; return true;
}); });
}
this.setState({ this.setState({
displayedWords, displayedWords,
stats: getWordsStats(words, partsOfSpeech, this.state.settings.caseSensitive), stats: getWordsStats(words, partsOfSpeech, this.state.settings.caseSensitive),
wordsInCurrentList,
}, () => callback()); }, () => callback());
}); });
} }
@ -209,6 +210,7 @@ class App extends Component {
dictionaryInfo={ this.dictionaryInfo } dictionaryInfo={ this.dictionaryInfo }
wordsToDisplay={ this.state.displayedWords } wordsToDisplay={ this.state.displayedWords }
wordsAreFiltered={ this.isUsingFilter } wordsAreFiltered={ this.isUsingFilter }
wordsInCurrentList={ this.state.wordsInCurrentList }
currentPage={ this.state.currentPage } currentPage={ this.state.currentPage }
itemsPerPage={ this.state.itemsPerPage } itemsPerPage={ this.state.itemsPerPage }
stats={ this.state.stats } stats={ this.state.stats }