List.js

  1import { withStyles } from '@material-ui/core/styles'
  2import Table from '@material-ui/core/Table/Table'
  3import TableBody from '@material-ui/core/TableBody/TableBody'
  4import TablePagination from '@material-ui/core/TablePagination/TablePagination'
  5import React from 'react'
  6import BugRow from './BugRow'
  7
  8const styles = theme => ({
  9  main: {
 10    maxWidth: 600,
 11    margin: 'auto',
 12    marginTop: theme.spacing.unit * 4
 13  }
 14})
 15
 16class List extends React.Component {
 17
 18  props: {
 19    bugs: Array,
 20    fetchMore: (any) => any,
 21    classes: any,
 22  }
 23
 24  state = {
 25    page: 0,
 26    rowsPerPage: 10,
 27    lastQuery: {}
 28  }
 29
 30  handleChangePage = (event, page) => {
 31    const {bugs, fetchMore} = this.props
 32    const {rowsPerPage} = this.state
 33    const pageInfo = bugs.pageInfo
 34
 35    if (page === this.state.page + 1) {
 36      if (!pageInfo.hasNextPage) {
 37        return
 38      }
 39
 40      const variables = {
 41        after: pageInfo.endCursor,
 42        first: rowsPerPage
 43      }
 44
 45      fetchMore({
 46        variables,
 47        updateQuery: this.updateQuery,
 48      })
 49
 50      this.setState({page, lastQuery: variables})
 51      return
 52    }
 53
 54    if (page === this.state.page - 1) {
 55      if (!pageInfo.hasPreviousPage) {
 56        return
 57      }
 58
 59      const variables = {
 60        before: pageInfo.startCursor,
 61        last: rowsPerPage
 62      }
 63
 64      fetchMore({
 65        variables,
 66        updateQuery: this.updateQuery,
 67      })
 68
 69      this.setState({page, lastQuery: variables})
 70      return
 71    }
 72
 73    throw new Error('non neighbour page pagination is not supported')
 74  }
 75
 76  handleChangeRowsPerPage = event => {
 77    const {fetchMore} = this.props
 78    const {lastQuery} = this.state
 79    const rowsPerPage = event.target.value
 80
 81    const variables = lastQuery
 82
 83    if (lastQuery.first) {
 84      variables.first = rowsPerPage
 85    } else if (lastQuery.last) {
 86      variables.last = rowsPerPage
 87    } else {
 88      variables.first = rowsPerPage
 89    }
 90
 91    fetchMore({
 92      variables,
 93      updateQuery: this.updateQuery,
 94    })
 95
 96    this.setState({rowsPerPage, lastQuery: variables})
 97  }
 98
 99  updateQuery = (previousResult, {fetchMoreResult}) => {
100    return fetchMoreResult ? fetchMoreResult : previousResult
101  }
102
103  render() {
104    const {classes, bugs} = this.props
105    const {page, rowsPerPage} = this.state
106
107    return (
108      <main className={classes.main}>
109        <Table className={classes.table}>
110          <TableBody>
111            {bugs.edges.map(({cursor, node}) => (
112              <BugRow bug={node} key={cursor}/>
113            ))}
114          </TableBody>
115        </Table>
116        <TablePagination
117          component="div"
118          count={bugs.totalCount}
119          rowsPerPage={rowsPerPage}
120          page={page}
121          backIconButtonProps={{
122            'aria-label': 'Previous Page'
123          }}
124          nextIconButtonProps={{
125            'aria-label': 'Next Page'
126          }}
127          onChangePage={this.handleChangePage}
128          onChangeRowsPerPage={this.handleChangeRowsPerPage}
129        />
130      </main>
131    )
132  }
133}
134
135export default withStyles(styles)(List)