Skip to content

Commit

Permalink
only enable pagination if limit/offset match pagination size
Browse files Browse the repository at this point in the history
  • Loading branch information
karooolis committed Feb 7, 2025
1 parent 6795f30 commit da738fa
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ import { TData, TDataRow, useTableDataQuery } from "../../../../queries/useTable
import { indexerForChainId } from "../../../../utils/indexerForChainId";
import { EditableTableCell } from "./EditableTableCell";
import { ExportButton } from "./ExportButton";
import { PAGE_SIZE_OPTIONS } from "./consts";
import { getLimitOffset } from "./utils/getLimitOffset";
import { typeSortingFn } from "./utils/typeSortingFn";

const initialSortingState: SortingState = [];
Expand Down Expand Up @@ -153,6 +155,16 @@ export function TablesViewer({ table, isLiveQuery }: Props) {
},
});

// Pagination is only enabled if the query has a LIMIT and OFFSET that are divisible by the page size
const isPaginationEnabled = useMemo(() => {
if (!query) return false;

const { limit, offset } = getLimitOffset(query);
if (limit == null || offset == null) return false;

return PAGE_SIZE_OPTIONS.includes(limit) && offset % pagination.pageSize === 0;
}, [pagination.pageSize, query]);

return (
<div
className={cn("space-y-4", {
Expand Down Expand Up @@ -237,12 +249,13 @@ export function TablesViewer({ table, isLiveQuery }: Props) {
<Select
value={pagination.pageSize.toString()}
onValueChange={(value) => reactTable.setPageSize(Number(value))}
disabled={!isPaginationEnabled}
>
<SelectTrigger className="h-8 w-[70px]">
<SelectValue>{pagination.pageSize}</SelectValue>
</SelectTrigger>
<SelectContent>
{[5, 10, 20, 30, 40, 50, 100].map((pageSize) => (
{PAGE_SIZE_OPTIONS.map((pageSize) => (
<SelectItem key={pageSize} value={pageSize.toString()}>
{pageSize}
</SelectItem>
Expand All @@ -257,23 +270,28 @@ export function TablesViewer({ table, isLiveQuery }: Props) {
variant="outline"
size="sm"
onClick={() => reactTable.setPageIndex(0)}
disabled={!reactTable.getCanPreviousPage()}
disabled={!isPaginationEnabled || !reactTable.getCanPreviousPage()}
>
<ChevronsLeftIcon className="mr-1 h-4 w-4" />
</Button>
<Button
variant="outline"
size="sm"
onClick={() => reactTable.previousPage()}
disabled={!reactTable.getCanPreviousPage()}
disabled={!isPaginationEnabled || !reactTable.getCanPreviousPage()}
>
<ChevronLeftIcon className="mr-1 h-4 w-4" /> Prev
</Button>
<Button
variant="outline"
size="sm"
onClick={() => reactTable.nextPage()}
disabled={!reactTable.getCanNextPage() || !tableData || tableData.rows.length < pagination.pageSize}
disabled={
!isPaginationEnabled ||
!reactTable.getCanNextPage() ||
!tableData ||
tableData.rows.length < pagination.pageSize
}
>
Next <ChevronRightIcon className="ml-1 h-4 w-4" />
</Button>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,3 +94,5 @@ export const suggestedSQLKeywords = [
"EXCEPT",
] as const;
export type SuggestedSQLKeyword = (typeof suggestedSQLKeywords)[number];

export const PAGE_SIZE_OPTIONS = [5, 10, 20, 30, 40, 50, 100];
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { Parser } from "node-sql-parser";

const sqlParser = new Parser();
const opt = {
database: "Postgresql",
};

export function getLimitOffset(query: string) {
const decodedQuery = decodeURIComponent(query);
let ast = sqlParser.astify(decodedQuery, opt);
if (Array.isArray(ast) && ast.length > 0) {
const astFirst = ast[0];
if (astFirst) {
ast = astFirst;
}
}

let limit = null;
let offset = null;

if ("limit" in ast) {
// If limit has a separator "offset", it contains both limit and offset values. Otherwise, only limit is set.
if (ast.limit?.seperator === "offset") {
limit = ast.limit?.value?.[0]?.value;
offset = ast.limit?.value?.[1]?.value;
} else {
limit = ast.limit?.value?.[0]?.value;
}
}

return { limit, offset };
}

0 comments on commit da738fa

Please sign in to comment.