From 23af4498535d9093c4568f0acf0e370ee714f56b Mon Sep 17 00:00:00 2001 From: Piero Toffanin Date: Wed, 12 Apr 2017 11:52:40 -0400 Subject: [PATCH] State history for pagination working --- app/static/app/js/Dashboard.jsx | 23 ++++++-- app/static/app/js/classes/HistoryNav.js | 17 ++++++ app/static/app/js/classes/Utils.js | 25 +++++++++ app/static/app/js/components/Paginated.jsx | 56 ++++++++------------ app/static/app/js/components/Paginator.jsx | 11 ++-- app/static/app/js/components/ProjectList.jsx | 17 ++++-- package.json | 2 + 7 files changed, 103 insertions(+), 48 deletions(-) create mode 100644 app/static/app/js/classes/HistoryNav.js diff --git a/app/static/app/js/Dashboard.jsx b/app/static/app/js/Dashboard.jsx index 91b043bd..0e8a17b4 100644 --- a/app/static/app/js/Dashboard.jsx +++ b/app/static/app/js/Dashboard.jsx @@ -2,6 +2,11 @@ import React from 'react'; import './css/Dashboard.scss'; import ProjectList from './components/ProjectList'; import EditProjectDialog from './components/EditProjectDialog'; +import Utils from './classes/Utils'; +import { + BrowserRouter as Router, + Route +} from 'react-router-dom'; import $ from 'jquery'; class Dashboard extends React.Component { @@ -32,7 +37,20 @@ class Dashboard extends React.Component { } render() { + const projectList = ({ location, history }) => { + let q = Utils.queryParams(location), + page = parseInt(q.page); + + return { this.projectList = domNode; }} + currentPage={page} + history={history} + />; + }; + return ( +
+ ); } } diff --git a/app/static/app/js/classes/HistoryNav.js b/app/static/app/js/classes/HistoryNav.js new file mode 100644 index 00000000..33d1a607 --- /dev/null +++ b/app/static/app/js/classes/HistoryNav.js @@ -0,0 +1,17 @@ +import Utils from './Utils'; + +class HistoryNav{ + constructor(history){ + this.history = history; + } + + changeQueryString(param, value){ + this.history.replace( + this.history.location.pathname + + Utils.replaceSearchQueryParam(this.history.location, param, value) + + this.history.location.hash); + } +} + +export default HistoryNav; + diff --git a/app/static/app/js/classes/Utils.js b/app/static/app/js/classes/Utils.js index a57230c6..f45da953 100644 --- a/app/static/app/js/classes/Utils.js +++ b/app/static/app/js/classes/Utils.js @@ -25,5 +25,30 @@ export default { return result; }, + + queryParams: function(location){ + let params = {}; + let paramsRaw = (location.search.replace("?", "").match(/([^&=]+)=?([^&]*)/g) || []); + for (let i in paramsRaw){ + let parts = paramsRaw[i].split("="); + params[parts[0]] = parts[1]; + } + return params; + }, + + toSearchQuery: function(params){ + let parts = []; + for (let k in params){ + parts.push(encodeURIComponent(k) + "=" + encodeURIComponent(params[k])); + } + if (parts.length > 0) return "?" + parts.join("&"); + else return ""; + }, + + replaceSearchQueryParam: function(location, param, value){ + let q = this.queryParams(location); + q[param] = value; + return this.toSearchQuery(q); + } }; diff --git a/app/static/app/js/components/Paginated.jsx b/app/static/app/js/components/Paginated.jsx index d2eae9dc..8e43ed96 100644 --- a/app/static/app/js/components/Paginated.jsx +++ b/app/static/app/js/components/Paginated.jsx @@ -1,27 +1,33 @@ import React from 'react'; import update from 'immutability-helper'; +import HistoryNav from '../classes/HistoryNav'; class Paginated extends React.Component{ - constructor(){ - super(); - this.handlePageChange = this.handlePageChange.bind(this); + static defaultProps = { + currentPage: 1 + }; + + static propTypes = { + history: React.PropTypes.object.isRequired, // reference to the history object coming from the route this component is bound to + currentPage: React.PropTypes.number + }; + + constructor(props){ + super(props); + + this.historyNav = new HistoryNav(props.history); } updatePagination(itemsPerPage, totalItems){ - let currentPage = 1; + let currentPage = this.props.currentPage; const totalPages = this.totalPages(itemsPerPage, totalItems); - if (this.state.pagination && this.state.pagination.currentPage !== undefined){ - currentPage = this.state.pagination.currentPage; - } - if (currentPage > totalPages) currentPage = totalPages; this.setState({pagination: { - switchingPages: false, + switchingPages: false, itemsPerPage: itemsPerPage, - totalItems: totalItems, - currentPage: currentPage + totalItems: totalItems } }); } @@ -30,14 +36,6 @@ class Paginated extends React.Component{ return Math.ceil(totalItems / itemsPerPage); } - getPaginatedUrl(base){ - const page = this.state.pagination && this.state.pagination.currentPage !== undefined - ? this.state.pagination.currentPage - : 1; - - return base.replace(/#\{PAGE\}/g, page); - } - setPaginationState(props, done){ this.setState(update(this.state, { pagination: { @@ -46,29 +44,17 @@ class Paginated extends React.Component{ }), done); } - handlePageChange(pageNum){ - return (e) => { - // Update current page, once rendering is completed, raise - // on page changed event - this.setPaginationState({ - currentPage: pageNum, - switchingPages: true - }, () => { - if (this.onPageChanged) this.onPageChanged(pageNum); - }); - } - } - handlePageItemsNumChange(delta, needsRefreshCallback){ + let currentPage = this.props.currentPage; const pagesBefore = this.totalPages(this.state.pagination.itemsPerPage, this.state.pagination.totalItems), pagesAfter = this.totalPages(this.state.pagination.itemsPerPage, this.state.pagination.totalItems + delta); - let currentPage = this.state.pagination.currentPage; if (currentPage > pagesAfter) currentPage = pagesAfter; + this.historyNav.changeQueryString('page', currentPage); + this.setPaginationState({ - totalItems: this.state.pagination.totalItems + delta, - currentPage: currentPage + totalItems: this.state.pagination.totalItems + delta }, () => { if (pagesBefore !== pagesAfter) needsRefreshCallback(pagesAfter); }); diff --git a/app/static/app/js/components/Paginator.jsx b/app/static/app/js/components/Paginator.jsx index 880e93d3..ad864a78 100644 --- a/app/static/app/js/components/Paginator.jsx +++ b/app/static/app/js/components/Paginator.jsx @@ -1,4 +1,5 @@ import React from 'react'; +import { Link } from 'react-router-dom'; import $ from 'jquery'; class Paginator extends React.Component { @@ -14,20 +15,20 @@ class Paginator extends React.Component {
); }else{ return (
- - + +
    {this.state.projects.map(p => ( diff --git a/package.json b/package.json index 5428b49a..6622163a 100644 --- a/package.json +++ b/package.json @@ -44,6 +44,8 @@ "react": "^15.3.2", "react-dom": "^15.3.2", "react-hot-loader": "^3.0.0-beta.5", + "react-router": "^4.1.0", + "react-router-dom": "^4.1.0", "sass-loader": "^4.0.2", "style-loader": "^0.13.1", "tween.js": "^16.6.0",