aboutsummaryrefslogtreecommitdiffstats
path: root/webui
diff options
context:
space:
mode:
authorMichael Muré <batolettre@gmail.com>2018-08-15 15:30:06 +0200
committerMichael Muré <batolettre@gmail.com>2018-08-15 15:30:06 +0200
commit24d862a65c603de4ea77a2688f5c90effc65be2f (patch)
tree48dc4cd97dc60d511988a52e428583686e9a4150 /webui
parentbc1fb34c24e985b7a9d50c559d7a42726a3a2007 (diff)
downloadgit-bug-24d862a65c603de4ea77a2688f5c90effc65be2f.tar.gz
webUI: implement pagination on the bug list
Diffstat (limited to 'webui')
-rw-r--r--webui/src/ListPage.js148
1 files changed, 133 insertions, 15 deletions
diff --git a/webui/src/ListPage.js b/webui/src/ListPage.js
index 76350ec5..31f010c0 100644
--- a/webui/src/ListPage.js
+++ b/webui/src/ListPage.js
@@ -1,7 +1,9 @@
+// @flow
import CircularProgress from '@material-ui/core/CircularProgress'
import { withStyles } from '@material-ui/core/styles'
import Table from '@material-ui/core/Table/Table'
import TableBody from '@material-ui/core/TableBody/TableBody'
+import TablePagination from '@material-ui/core/TablePagination/TablePagination'
import gql from 'graphql-tag'
import React from 'react'
import { Query } from 'react-apollo'
@@ -9,19 +11,27 @@ import { Query } from 'react-apollo'
import BugSummary from './BugSummary'
const QUERY = gql`
- {
+ query($first: Int = 10, $last: Int, $after: String, $before: String) {
defaultRepository {
- bugs: allBugs(first: 10) {
+ bugs: allBugs(first: $first, last: $last, after: $after, before: $before) {
+ totalCount
edges {
cursor
node {
...BugSummary
}
}
+ pageInfo{
+ hasNextPage
+ hasPreviousPage
+ startCursor
+ endCursor
+ }
}
}
}
+
${BugSummary.fragment}
`
@@ -33,24 +43,132 @@ const styles = theme => ({
}
})
-const List = withStyles(styles)(({bugs, classes}) => (
- <main className={classes.main}>
- <Table className={classes.table}>
- <TableBody>
- {bugs.edges.map(({ cursor, node }) => (
- <BugSummary bug={node} key={cursor} />
- ))}
- </TableBody>
- </Table>
- </main>
-))
+const List = withStyles(styles)(class List extends React.Component {
+
+ props: {
+ bugs: Array,
+ fetchMore: (any) => any,
+ classes: any,
+ }
+
+ state = {
+ page: 0,
+ rowsPerPage: 10,
+ lastQuery: {}
+ }
+
+ handleChangePage = (event, page) => {
+ const {bugs, fetchMore} = this.props
+ const {rowsPerPage} = this.state
+ const pageInfo = bugs.pageInfo
+
+ if (page === this.state.page + 1) {
+ if (!pageInfo.hasNextPage) {
+ return
+ }
+
+ const variables = {
+ after: pageInfo.endCursor,
+ first: rowsPerPage
+ }
+
+ fetchMore({
+ variables,
+ updateQuery: this.updateQuery,
+ })
+
+ this.setState({page, lastQuery: variables})
+ return
+ }
+
+ if (page === this.state.page - 1) {
+ if (!pageInfo.hasPreviousPage) {
+ return
+ }
+
+ const variables = {
+ before: pageInfo.startCursor,
+ last: rowsPerPage
+ }
+
+ fetchMore({
+ variables,
+ updateQuery: this.updateQuery,
+ })
+
+ this.setState({page, lastQuery: variables})
+ return
+ }
+
+ throw 'non neighbour page pagination is not supported'
+ }
+
+ handleChangeRowsPerPage = event => {
+ const {fetchMore} = this.props
+ const {lastQuery} = this.state
+ const rowsPerPage = event.target.value
+
+ const variables = lastQuery
+
+ if (lastQuery.first) {
+ variables.first = rowsPerPage
+ } else if (lastQuery.last) {
+ variables.last = rowsPerPage
+ } else {
+ variables.first = rowsPerPage
+ }
+
+ fetchMore({
+ variables,
+ updateQuery: this.updateQuery,
+ })
+
+ this.setState({rowsPerPage, lastQuery: variables})
+ }
+
+ updateQuery = (previousResult, {fetchMoreResult}) => {
+ console.log(fetchMoreResult)
+ return fetchMoreResult ? fetchMoreResult : previousResult
+ }
+
+ render() {
+ const {classes, bugs} = this.props
+ const {page, rowsPerPage} = this.state
+
+ return (
+ <main className={classes.main}>
+ <Table className={classes.table}>
+ <TableBody>
+ {bugs.edges.map(({cursor, node}) => (
+ <BugSummary bug={node} key={cursor}/>
+ ))}
+ </TableBody>
+ </Table>
+ <TablePagination
+ component="div"
+ count={bugs.totalCount}
+ rowsPerPage={rowsPerPage}
+ page={page}
+ backIconButtonProps={{
+ 'aria-label': 'Previous Page'
+ }}
+ nextIconButtonProps={{
+ 'aria-label': 'Next Page'
+ }}
+ onChangePage={this.handleChangePage}
+ onChangeRowsPerPage={this.handleChangeRowsPerPage}
+ />
+ </main>
+ )
+ }
+})
const ListPage = () => (
<Query query={QUERY}>
- {({loading, error, data}) => {
+ {({loading, error, data, fetchMore}) => {
if (loading) return <CircularProgress/>
if (error) return <p>Error.</p>
- return <List bugs={data.defaultRepository.bugs}/>
+ return <List bugs={data.defaultRepository.bugs} fetchMore={fetchMore}/>
}}
</Query>
)