diff --git a/package-lock.json b/package-lock.json index c40efb685..67c2f6f0e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -80,6 +80,7 @@ "react-router-dom": "^5.2.0", "react-share": "^4.2.0", "react-syntax-highlighter": "^15.4.3", + "react-table": "^7.8.0", "react-table-6": "^6.11.0", "react-tagsinput": "^3.19.0", "redux": "^4.1.2", @@ -11036,6 +11037,19 @@ "react": ">= 0.14.0" } }, + "node_modules/react-table": { + "version": "7.8.0", + "resolved": "https://registry.npmjs.org/react-table/-/react-table-7.8.0.tgz", + "integrity": "sha512-hNaz4ygkZO4bESeFfnfOft73iBUj8K5oKi1EcSHPAibEydfsX2MyU6Z8KCr3mv3C9Kqqh71U+DhZkFvibbnPbA==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + }, + "peerDependencies": { + "react": "^16.8.3 || ^17.0.0-0 || ^18.0.0" + } + }, "node_modules/react-table-6": { "version": "6.11.0", "resolved": "https://registry.npmjs.org/react-table-6/-/react-table-6-6.11.0.tgz", diff --git a/package.json b/package.json index 3a104f89d..3b23bc9c2 100644 --- a/package.json +++ b/package.json @@ -102,6 +102,7 @@ "react-router-dom": "^5.2.0", "react-share": "^4.2.0", "react-syntax-highlighter": "^15.4.3", + "react-table": "^7.8.0", "react-table-6": "^6.11.0", "react-tagsinput": "^3.19.0", "redux": "^4.1.2", diff --git a/src/components/PaginationControl/PaginationControl.jsx b/src/components/PaginationControl/PaginationControl.jsx new file mode 100644 index 000000000..dcc0bf6ea --- /dev/null +++ b/src/components/PaginationControl/PaginationControl.jsx @@ -0,0 +1,75 @@ +export default function PaginationControl({ + currentPage, + totalPages, + pageSize, + gotoPage, + setPageSize, +}) { + const canPreviousPage = currentPage > 0; + const canNextPage = currentPage < totalPages - 1; + + const previousPage = () => gotoPage(Math.max(currentPage - 1, 0)); + const nextPage = () => gotoPage(Math.min(currentPage + 1, totalPages - 1)); + + return ( +
+ + + + {"Page "} + gotoPage(e.target.value ? Number(e.target.value) - 1 : 0)} + /> + {" of "} + {totalPages} + + + + + {setPageSize && ( + + )} +
+ ); +} diff --git a/src/pages/Sent/Sent.jsx b/src/pages/Sent/Sent.jsx index 36d7d9ffa..ad87a8b91 100644 --- a/src/pages/Sent/Sent.jsx +++ b/src/pages/Sent/Sent.jsx @@ -1,20 +1,19 @@ import { useEffect, useState } from "react"; import { FormattedDate, FormattedTime, injectIntl } from "react-intl"; import { Link } from "react-router-dom"; -import ReactTable from "react-table-6"; +import { usePagination, useSortBy, useTable } from "react-table"; import WithCurrentUser from "../../components/HOCs/WithCurrentUser/WithCurrentUser"; -import { intlTableProps } from "../../components/IntlTable/IntlTable"; +import PaginationControl from "../../components/PaginationControl/PaginationControl"; import CommentType from "../../services/Comment/CommentType"; import HeaderSent from "./HeaderSent"; -import Notification from "./Notification"; import { useSentComments } from "./SentCommentsHooks"; -const defaultSorted = { +const DEFAULT_SORT_CRITERIA = { id: "created", desc: true, }; -const defaultPagination = { +const DEFAULT_PAGINATION = { page: 0, pageSize: 25, }; @@ -22,9 +21,30 @@ const defaultPagination = { const Sent = (props) => { const [commentType, setCommentType] = useState(CommentType.TASK); const comments = useSentComments(commentType); - const [sortCriteria, setSortCriteria] = useState(defaultSorted); - const [pagination, setPagination] = useState(defaultPagination); - const [selectedComment, setSelectedComment] = useState(null); + const [sortCriteria, setSortCriteria] = useState(DEFAULT_SORT_CRITERIA); + const [pagination, setPagination] = useState(DEFAULT_PAGINATION); + + const data = comments.data; + const columns = commentType === CommentType.TASK ? TASK_COLUMNS : CHALLENGE_COLUMNS; + + const { + getTableProps, + getTableBodyProps, + headerGroups, + rows, + prepareRow, + state: { sortBy }, + } = useTable( + { + data, + columns, + manualPagination: true, + manualSortBy: true, + pageCount: comments.count, + }, + useSortBy, + usePagination, + ); useEffect(() => { comments.fetch(props.user?.id, sortCriteria, pagination); @@ -37,13 +57,19 @@ const Sent = (props) => { pagination.pageSize, ]); + useEffect(() => { + if (sortBy && sortBy[0]) setSortCriteria(sortBy[0]); + }, [sortBy]); + const resetTable = () => { - setSortCriteria(defaultSorted); - setPagination(defaultPagination); + setSortCriteria(DEFAULT_SORT_CRITERIA); + setPagination(DEFAULT_PAGINATION); }; + const totalPages = Math.ceil(comments.count / pagination.pageSize); + return ( -
+
{ resetTable(); }} /> - { - setSortCriteria(criteria[0]); - }} - onPageChange={(page) => setPagination({ ...pagination, page })} - onPageSizeChange={(pageSize) => setPagination({ ...pagination, pageSize })} - page={pagination.page} - getTrProps={() => { - const styles = {}; - return { style: styles }; - }} - {...intlTableProps(props.intl)} - > - {(state, makeTable) => { - return makeTable(); - }} - + + + + {headerGroups.map((headerGroup) => ( + + {headerGroup.headers.map((column) => ( + + ))} + + ))} + + + + {rows.map((row) => { + prepareRow(row); + return ( + + {row.cells.map((cell) => { + return ( + + ); + })} + + ); + })} + +
+ {column.render("Header")} + {column.isSorted ? (column.isSortedDesc ? " ▼" : " ▲") : ""} +
+ {cell.render("Cell")} +
- {selectedComment && ( - setSelectedComment(null)} - id={selectedComment.id} - text={selectedComment.text} - type={selectedComment.type} - /> - )} + setPagination({ ...pagination, page })} + setPageSize={(pageSize) => setPagination({ ...pagination, pageSize })} + />
); }; -const taskColumns = ({ setSelectedComment }) => [ +const TASK_COLUMNS = [ { id: "task_id", Header: "Task ID", accessor: "taskId", - Cell: ({ value }) => ( - - {value} - - ), - maxWidth: 100, + Cell: ({ value }) => {value}, sortable: true, resizable: false, }, @@ -119,11 +138,10 @@ const taskColumns = ({ setSelectedComment }) => [ Header: "Date", accessor: "created", Cell: ({ value }) => ( - <> +
- +
), - maxWidth: 200, sortable: true, resizable: false, }, @@ -131,40 +149,20 @@ const taskColumns = ({ setSelectedComment }) => [ id: "comment", Header: "Comment", accessor: "comment", - Cell: ({ value, row }) => { - return ( - - ); - }, + Cell: ({ value }) =>

{value}

, sortable: true, resizable: false, }, ]; -const challengeColumns = ({ setSelectedComment }) => [ +const CHALLENGE_COLUMNS = [ { id: "challenge_name", Header: "Challenge", accessor: "challengeName", - Cell: ({ value, original }) => { - return ( - - {value} - - ); - }, + Cell: ({ value, original }) => ( + {value} + ), maxWidth: 200, sortable: true, resizable: false, @@ -174,9 +172,9 @@ const challengeColumns = ({ setSelectedComment }) => [ Header: "Date", accessor: "created", Cell: ({ value }) => ( - <> +
- +
), maxWidth: 200, sortable: true, @@ -186,23 +184,7 @@ const challengeColumns = ({ setSelectedComment }) => [ id: "comment", Header: "Comment", accessor: "comment", - Cell: ({ value, original }) => { - return ( - - ); - }, + Cell: ({ value }) =>

{value}

, sortable: true, resizable: false, }, diff --git a/src/styles/vendor/react-table.css b/src/styles/vendor/react-table.css index 1844ffad8..59f93e296 100644 --- a/src/styles/vendor/react-table.css +++ b/src/styles/vendor/react-table.css @@ -3,21 +3,20 @@ .ReactTable { @apply mr-border-none mr-text-white; - .rt-table { + table { @apply mr-mb-3; } - .rt-thead { + thead { &.-header { @apply mr-shadow-none mr-border-b mr-border-white-15; } - .rt-tr { + tr { @apply mr-text-left; } - .rt-th, - .rt-tb { + th { @apply mr-outline-none mr-border-none mr-p-4 mr-text-white mr-text-xs mr-font-medium mr-uppercase mr-tracking-wide; line-height: 1rem; @@ -33,7 +32,7 @@ &.-filters { @apply mr-border-none; - .rt-th { + th { @apply mr-border-none mr-pb-0 mr-pt-4; } @@ -47,16 +46,16 @@ } } - .rt-td { + td { @apply mr-p-3 mr-text-sm; } - .rt-tbody { + tbody { .rt-tr-group { @apply mr-border-white-15; } - .rt-td { + td { @apply mr-border-r-0 mr-p-4 mr-leading-normal; } }