🏗️ Fixed pagination and disabled states

This commit is contained in:
2023-11-16 08:53:25 -06:00
parent b1d63b02c4
commit 3699ca8b2a
2 changed files with 89 additions and 95 deletions

View File

@@ -1,4 +1,10 @@
import React, { useMemo, ReactElement, useCallback, useEffect } from "react"; import React, {
useMemo,
ReactElement,
useCallback,
useEffect,
useState,
} from "react";
import PropTypes from "prop-types"; import PropTypes from "prop-types";
import { useNavigate } from "react-router-dom"; import { useNavigate } from "react-router-dom";
import { isEmpty, isNil, isUndefined } from "lodash"; import { isEmpty, isNil, isUndefined } from "lodash";
@@ -6,7 +12,7 @@ import MetadataPanel from "../shared/MetadataPanel";
import T2Table from "../shared/T2Table"; import T2Table from "../shared/T2Table";
import { searchIssue } from "../../actions/fileops.actions"; import { searchIssue } from "../../actions/fileops.actions";
import ellipsize from "ellipsize"; import ellipsize from "ellipsize";
import { useQuery } from "@tanstack/react-query"; import { useQuery, keepPreviousData } from "@tanstack/react-query";
import axios from "axios"; import axios from "axios";
/** /**
@@ -17,29 +23,31 @@ import axios from "axios";
* <Library /> * <Library />
*/ */
export const Library = (): ReactElement => { export const Library = (): ReactElement => {
// const searchResults = useSelector( // Default page state
// (state: RootState) => state.fileOps.libraryComics, // 15 issues per page, offset: 0
// ); const [page, setPage] = useState(0);
// const searchError = useSelector( // Method to fetch paginated issues
// (state: RootState) => state.fileOps.librarySearchError, const fetchIssues = async (searchQuery, page, type) => {
// ); let pagination = {
// const dispatch = useDispatch(); size: 15,
const { data, isLoading, isError } = useQuery({ from: page,
queryKey: ["comics"], };
queryFn: async () => return await axios({
axios({ method: "POST",
method: "POST", url: "http://localhost:3000/api/search/searchIssue",
url: "http://localhost:3000/api/search/searchIssue", data: {
data: { searchQuery,
query: {}, pagination,
pagination: { type,
size: 15, },
from: 0, });
}, };
type: "all", const { data, isLoading, isError, isPlaceholderData } = useQuery({
}, queryKey: ["comics", page],
}), queryFn: () => fetchIssues({}, page, "all"),
placeholderData: keepPreviousData,
}); });
const searchResults = data?.data; const searchResults = data?.data;
console.log(searchResults); console.log(searchResults);
// programatically navigate to comic detail // programatically navigate to comic detail
@@ -159,23 +167,11 @@ export const Library = (): ReactElement => {
* @returns void * @returns void
* *
**/ **/
const nextPage = useCallback((pageIndex: number, pageSize: number) => { const nextPage = (pageIndex: number, pageSize: number) => {
// dispatch( if (!isPlaceholderData) {
// searchIssue( setPage(pageSize * pageIndex + 1);
// { }
// query: {}, };
// },
// {
// pagination: {
// size: pageSize,
// from: pageSize * pageIndex + 1,
// },
// type: "all",
// trigger: "libraryPage",
// },
// ),
// );
}, []);
/** /**
* Pagination control that fetches the previous x (pageSize) items * Pagination control that fetches the previous x (pageSize) items
@@ -184,29 +180,15 @@ export const Library = (): ReactElement => {
* @param {number} pageSize * @param {number} pageSize
* @returns void * @returns void
**/ **/
const previousPage = useCallback((pageIndex: number, pageSize: number) => { const previousPage = (pageIndex: number, pageSize: number) => {
let from = 0; let from = 0;
if (pageIndex === 2) { if (pageIndex === 2) {
from = (pageIndex - 1) * pageSize + 2 - 17; from = (pageIndex - 1) * pageSize + 2 - (pageSize + 2);
} else { } else {
from = (pageIndex - 1) * pageSize + 2 - 16; from = (pageIndex - 1) * pageSize + 2 - (pageSize + 1);
} }
// dispatch( setPage(from);
// searchIssue( };
// {
// query: {},
// },
// {
// pagination: {
// size: pageSize,
// from,
// },
// type: "all",
// trigger: "libraryPage",
// },
// ),
// );
}, []);
// ImportStatus.propTypes = { // ImportStatus.propTypes = {
// value: PropTypes.bool.isRequired, // value: PropTypes.bool.isRequired,
@@ -217,13 +199,13 @@ export const Library = (): ReactElement => {
<div className="header-area"> <div className="header-area">
<h1 className="title">Library</h1> <h1 className="title">Library</h1>
</div> </div>
{!isUndefined(searchResults?.data?.data) ? ( {!isUndefined(searchResults) ? (
<div> <div>
<div className="library"> <div className="library">
<T2Table <T2Table
totalPages={searchResults.total.value} totalPages={searchResults.hits.total.value}
columns={columns} columns={columns}
sourceData={searchResults?.hits} sourceData={searchResults?.hits.hits}
rowClickHandler={navigateToComicDetail} rowClickHandler={navigateToComicDetail}
paginationHandlers={{ paginationHandlers={{
nextPage, nextPage,
@@ -242,14 +224,14 @@ export const Library = (): ReactElement => {
back. back.
</div> </div>
</article> </article>
<pre> {/* <pre>
{!isUndefined(searchResults?.code === 404 && !isLoading) && {!isUndefined(searchResults?.code === 404 && !isLoading) &&
JSON.stringify( JSON.stringify(
searchResults.data.meta.body.error.root_cause, searchResults.meta.body.error.root_cause,
null, null,
4, 4,
)} )}
</pre> </pre> */}
</div> </div>
</div> </div>
)} )}

View File

@@ -12,26 +12,30 @@ import {
} from "@tanstack/react-table"; } from "@tanstack/react-table";
export const T2Table = (tableOptions): ReactElement => { export const T2Table = (tableOptions): ReactElement => {
const { sourceData, columns, paginationHandlers: { nextPage, previousPage }, totalPages, rowClickHandler } = const {
tableOptions; sourceData,
columns,
paginationHandlers: { nextPage, previousPage },
totalPages,
rowClickHandler,
} = tableOptions;
const [{ pageIndex, pageSize }, setPagination] = const [{ pageIndex, pageSize }, setPagination] = useState<PaginationState>({
useState<PaginationState>({ pageIndex: 1,
pageIndex: 1, pageSize: 15,
pageSize: 15, });
});
const pagination = useMemo( const pagination = useMemo(
() => ({ () => ({
pageIndex, pageIndex,
pageSize, pageSize,
}), }),
[pageIndex, pageSize] [pageIndex, pageSize],
); );
/** /**
* Pagination control to move forward one page * Pagination control to move forward one page
* @returns void * @returns void
*/ */
const goToNextPage = () => { const goToNextPage = () => {
setPagination({ setPagination({
@@ -39,10 +43,10 @@ export const T2Table = (tableOptions): ReactElement => {
pageSize, pageSize,
}); });
nextPage(pageIndex, pageSize); nextPage(pageIndex, pageSize);
} };
/** /**
* Pagination control to move backward one page * Pagination control to move backward one page
* @returns void * @returns void
**/ **/
const goToPreviousPage = () => { const goToPreviousPage = () => {
@@ -51,7 +55,7 @@ export const T2Table = (tableOptions): ReactElement => {
pageSize, pageSize,
}); });
previousPage(pageIndex, pageSize); previousPage(pageIndex, pageSize);
} };
const table = useReactTable({ const table = useReactTable({
data: sourceData, data: sourceData,
@@ -75,15 +79,29 @@ export const T2Table = (tableOptions): ReactElement => {
{/* pagination controls */} {/* pagination controls */}
<nav className="pagination columns"> <nav className="pagination columns">
<div className="mr-4 has-text-weight-semibold has-text-left"> <div className="mr-4 has-text-weight-semibold has-text-left">
<p className="is-size-5">Page {pageIndex} of {Math.ceil(totalPages / pageSize)}</p> <p className="is-size-5">
{/* <p>{totalPages} comics in all</p> */} Page {pageIndex} of {Math.ceil(totalPages / pageSize)}
</p>
<p>{totalPages} comics in all</p>
</div> </div>
<div className="field has-addons"> <div className="field has-addons">
<div className="control"> <div className="control">
<div className="button" onClick={() => goToPreviousPage()}> <i className="fas fa-chevron-left"></i></div> <button
className="button"
onClick={() => goToPreviousPage()}
disabled={pageIndex === 1}
>
<i className="fas fa-chevron-left"></i>
</button>
</div> </div>
<div className="control"> <div className="control">
<div className="button" onClick={() => goToNextPage()}> <i className="fas fa-chevron-right"></i> </div> <button
className="button"
onClick={() => goToNextPage()}
disabled={pageIndex > Math.floor(totalPages / pageSize)}
>
<i className="fas fa-chevron-right"></i>
</button>
</div> </div>
<div className="field has-addons ml-5"> <div className="field has-addons ml-5">
@@ -112,16 +130,13 @@ export const T2Table = (tableOptions): ReactElement => {
{table.getHeaderGroups().map((headerGroup, idx) => ( {table.getHeaderGroups().map((headerGroup, idx) => (
<tr key={headerGroup.id}> <tr key={headerGroup.id}>
{headerGroup.headers.map((header, idx) => ( {headerGroup.headers.map((header, idx) => (
<th <th key={header.id} colSpan={header.colSpan}>
key={header.id}
colSpan={header.colSpan}
>
{header.isPlaceholder {header.isPlaceholder
? null ? null
: flexRender( : flexRender(
header.column.columnDef.header, header.column.columnDef.header,
header.getContext() header.getContext(),
)} )}
</th> </th>
))} ))}
</tr> </tr>
@@ -131,11 +146,8 @@ export const T2Table = (tableOptions): ReactElement => {
<tbody> <tbody>
{table.getRowModel().rows.map((row, idx) => { {table.getRowModel().rows.map((row, idx) => {
return ( return (
<tr <tr key={row.id} onClick={() => rowClickHandler(row)}>
key={row.id} {row.getVisibleCells().map((cell) => (
onClick={() => rowClickHandler(row)}
>
{row.getVisibleCells().map(cell => (
<td key={cell.id}> <td key={cell.id}>
{flexRender(cell.column.columnDef.cell, cell.getContext())} {flexRender(cell.column.columnDef.cell, cell.getContext())}
</td> </td>