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