1
0
Fork 0
mirror of https://github.com/Alamantus/Lexiconga.git synced 2025-06-27 11:24:19 +02:00

Add pagination to hopefully quell fears of storing too much in memory.

This commit is contained in:
Robbie Antenesse 2018-02-21 23:14:39 -07:00
parent f59f72eaac
commit 38c8f2dcd1
3 changed files with 93 additions and 3 deletions

View file

@ -4,6 +4,7 @@ import PropTypes from 'prop-types';
import { LeftColumn } from './structure/LeftColumn'; import { LeftColumn } from './structure/LeftColumn';
import { RightColumn } from './structure/RightColumn'; import { RightColumn } from './structure/RightColumn';
import { Pagination } from './structure/Pagination';
import { WordForm } from './management/WordForm'; import { WordForm } from './management/WordForm';
import { DictionaryDetails } from './display/DictionaryDetails'; import { DictionaryDetails } from './display/DictionaryDetails';
@ -17,6 +18,10 @@ 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,
currentPage: PropTypes.number,
itemsPerPage: PropTypes.number,
stats: PropTypes.object.isRequired,
setPage: PropTypes.func.isRequired,
updateDisplay: PropTypes.func.isRequired, updateDisplay: PropTypes.func.isRequired,
updater: PropTypes.object.isRequired, updater: PropTypes.object.isRequired,
}, props, 'prop', 'MainDisplay'); }, props, 'prop', 'MainDisplay');
@ -52,6 +57,10 @@ export class MainDisplay extends Component {
dictionaryInfo, dictionaryInfo,
wordsToDisplay, wordsToDisplay,
wordsAreFiltered, wordsAreFiltered,
currentPage,
itemsPerPage,
stats,
setPage,
updateDisplay, updateDisplay,
updater, updater,
} = this.props; } = this.props;
@ -100,6 +109,13 @@ export class MainDisplay extends Component {
words={ wordsToDisplay } words={ wordsToDisplay }
adsEveryXWords={ 10 } adsEveryXWords={ 10 }
updateDisplay={ updateDisplay } /> updateDisplay={ updateDisplay } />
<Pagination
currentPage={currentPage}
itemsPerPage={itemsPerPage}
totalWords={stats.hasOwnProperty('numberOfWords')
? stats.numberOfWords.find(group => group.name === 'Total').value : null}
setPage={ setPage } />
</RightColumn> </RightColumn>
</div> </div>

View file

@ -0,0 +1,51 @@
import Inferno from 'inferno';
import PropTypes from 'prop-types';
export const Pagination = (props) => {
PropTypes.checkPropTypes({
currentPage: PropTypes.number.isRequired,
itemsPerPage: PropTypes.number.isRequired,
totalWords: PropTypes.number,
setPage: PropTypes.func.isRequired,
}, props, 'prop', 'Pagination');
const { currentPage, itemsPerPage, totalWords, setPage } = props;
if (totalWords === null) {
return <div className="loader"></div>;
}
const lastPage = Math.floor(totalWords / itemsPerPage);
const nextPage = currentPage + 1 > lastPage ? lastPage : currentPage + 1;
const prevPage = currentPage - 1 < 0 ? 0 : currentPage - 1;
const changePage = (page) => {
if (page !== currentPage && page <= lastPage && page >= 0) {
setPage(page);
}
}
return (
<nav className="pagination is-centered" role="navigation" aria-label="pagination">
<a className="pagination-previous" aria-label="Goto page 1"
Disabled={currentPage === 0 ? 'disabled' : null}
onClick={() => changePage(prevPage)}>
Previous
</a>
<a className="pagination-next" aria-label={`Goto page ${lastPage + 1}`}
Disabled={currentPage === lastPage ? 'disabled' : null}
onClick={() => changePage(nextPage)}>
Next
</a>
<div className="pagination-list">
<div class="select">
<select value={currentPage} onChange={(event) => changePage(parseInt(event.target.value))}>
{[...new Array(lastPage + 1)].map((v, index) => {
return <option value={index}>{index + 1}</option>;
})}
</select>
</div>
</div>
</nav>
);
}

View file

@ -36,6 +36,8 @@ class App extends Component {
alphabeticalOrder: dictionary.alphabeticalOrder, alphabeticalOrder: dictionary.alphabeticalOrder,
displayedWords: [], displayedWords: [],
currentPage: 0,
itemsPerPage: 30,
searchConfig: { searchConfig: {
searchingIn: 'name', searchingIn: 'name',
searchMethod: SEARCH_METHOD.contains, searchMethod: SEARCH_METHOD.contains,
@ -90,9 +92,12 @@ class App extends Component {
} }
updateDisplayedWords (callback = () => {}) { updateDisplayedWords (callback = () => {}) {
const {currentPage, itemsPerPage} = this.state;
dictionary.wordsPromise.then(words => { dictionary.wordsPromise.then(words => {
const { searchConfig, partsOfSpeech } = this.state; const { searchConfig, partsOfSpeech, currentPage, itemsPerPage } = this.state;
const partsOfSpeechForFilter = [...partsOfSpeech, 'Uncategorized']; const partsOfSpeechForFilter = [...partsOfSpeech, 'Uncategorized'];
const pageStart = currentPage * itemsPerPage;
const pageEnd = pageStart + itemsPerPage;
let displayedWords; let displayedWords;
if (this.isUsingFilter) { if (this.isUsingFilter) {
const { const {
@ -104,7 +109,10 @@ class App extends Component {
filteredPartsOfSpeech filteredPartsOfSpeech
} = searchConfig; } = searchConfig;
displayedWords = words.filter((word) => { displayedWords = words.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;
@ -161,7 +169,12 @@ class App extends Component {
} }
}); });
} else { } else {
displayedWords = words; displayedWords = words.filter((word, index) => {
if (index < pageStart || index >= pageEnd) {
return false;
}
return true;
});
} }
this.setState({ this.setState({
@ -177,6 +190,12 @@ class App extends Component {
}, () => this.updateDisplayedWords()); }, () => this.updateDisplayedWords());
} }
setPage (newPage) {
this.setState({
currentPage: newPage,
}, () => this.updateDisplayedWords());
}
render () { render () {
return ( return (
<div> <div>
@ -190,6 +209,10 @@ class App extends Component {
dictionaryInfo={ this.dictionaryInfo } dictionaryInfo={ this.dictionaryInfo }
wordsToDisplay={ this.state.displayedWords } wordsToDisplay={ this.state.displayedWords }
wordsAreFiltered={ this.isUsingFilter } wordsAreFiltered={ this.isUsingFilter }
currentPage={ this.state.currentPage }
itemsPerPage={ this.state.itemsPerPage }
stats={ this.state.stats }
setPage={ this.setPage.bind(this) }
updateDisplay={ this.updateDisplayedWords.bind(this) } updateDisplay={ this.updateDisplayedWords.bind(this) }
updater={ this.updater } updater={ this.updater }
/> />