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:
parent
f59f72eaac
commit
38c8f2dcd1
3 changed files with 93 additions and 3 deletions
|
@ -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>
|
||||||
|
|
51
src/components/structure/Pagination.jsx
Normal file
51
src/components/structure/Pagination.jsx
Normal 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>
|
||||||
|
);
|
||||||
|
}
|
|
@ -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 }
|
||||||
/>
|
/>
|
||||||
|
|
Loading…
Add table
Reference in a new issue