diff options
Diffstat (limited to 'webui/src')
-rw-r--r-- | webui/src/list/List.js | 160 | ||||
-rw-r--r-- | webui/src/list/ListQuery.js | 39 |
2 files changed, 66 insertions, 133 deletions
diff --git a/webui/src/list/List.js b/webui/src/list/List.js index d36be8a1..45c2c963 100644 --- a/webui/src/list/List.js +++ b/webui/src/list/List.js @@ -1,134 +1,50 @@ -import { withStyles } from '@material-ui/core/styles'; +import { makeStyles } from '@material-ui/styles'; +import IconButton from '@material-ui/core/IconButton'; 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 KeyboardArrowLeft from '@material-ui/icons/KeyboardArrowLeft'; +import KeyboardArrowRight from '@material-ui/icons/KeyboardArrowRight'; import React from 'react'; import BugRow from './BugRow'; -const styles = theme => ({ +const useStyles = makeStyles(theme => ({ main: { maxWidth: 600, margin: 'auto', marginTop: theme.spacing.unit * 4, }, -}); - -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 new Error('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 }) => { - 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 }) => ( - <BugRow 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> - ); - } + pagination: { + ...theme.typography.overline, + display: 'flex', + alignItems: 'center', + justifyContent: 'flex-end', + }, +})); + +function List({ bugs, nextPage, prevPage }) { + const classes = useStyles(); + const { hasNextPage, hasPreviousPage } = bugs.pageInfo; + return ( + <main className={classes.main}> + <Table className={classes.table}> + <TableBody> + {bugs.edges.map(({ cursor, node }) => ( + <BugRow bug={node} key={cursor} /> + ))} + </TableBody> + </Table> + + <div className={classes.pagination}> + <div>Total: {bugs.totalCount}</div> + <IconButton onClick={prevPage} disabled={!hasPreviousPage}> + <KeyboardArrowLeft /> + </IconButton> + <IconButton onClick={nextPage} disabled={!hasNextPage}> + <KeyboardArrowRight /> + </IconButton> + </div> + </main> + ); } -export default withStyles(styles)(List); +export default List; diff --git a/webui/src/list/ListQuery.js b/webui/src/list/ListQuery.js index 9dbe4e53..869bca79 100644 --- a/webui/src/list/ListQuery.js +++ b/webui/src/list/ListQuery.js @@ -1,13 +1,13 @@ // @flow import CircularProgress from '@material-ui/core/CircularProgress'; import gql from 'graphql-tag'; -import React from 'react'; +import React, { useState } from 'react'; import { Query } from 'react-apollo'; import BugRow from './BugRow'; import List from './List'; const QUERY = gql` - query($first: Int = 10, $last: Int, $after: String, $before: String) { + query($first: Int, $last: Int, $after: String, $before: String) { defaultRepository { bugs: allBugs( first: $first @@ -35,14 +35,31 @@ const QUERY = gql` ${BugRow.fragment} `; -const ListQuery = () => ( - <Query query={QUERY}> - {({ loading, error, data, fetchMore }) => { - if (loading) return <CircularProgress />; - if (error) return <p>Error: {error}</p>; - return <List bugs={data.defaultRepository.bugs} fetchMore={fetchMore} />; - }} - </Query> -); +function ListQuery() { + const [page, setPage] = useState({ first: 10, after: null }); + + const perPage = page.first || page.last; + const nextPage = pageInfo => + setPage({ first: perPage, after: pageInfo.endCursor }); + const prevPage = pageInfo => + setPage({ last: perPage, before: pageInfo.startCursor }); + + return ( + <Query query={QUERY} variables={page}> + {({ loading, error, data }) => { + if (loading) return <CircularProgress />; + if (error) return <p>Error: {error}</p>; + const bugs = data.defaultRepository.bugs; + return ( + <List + bugs={bugs} + nextPage={() => nextPage(bugs.pageInfo)} + prevPage={() => prevPage(bugs.pageInfo)} + /> + ); + }} + </Query> + ); +} export default ListQuery; |