diff --git a/apps/hub/app/_components/PaginatedTable.tsx b/apps/hub/app/_components/PaginatedTable.tsx index f9f6edb3..2b82f1ba 100644 --- a/apps/hub/app/_components/PaginatedTable.tsx +++ b/apps/hub/app/_components/PaginatedTable.tsx @@ -1,6 +1,6 @@ "use client"; -import { useState, Ref, useImperativeHandle } from "react"; -import SortableTable, { Pagination, SortableTableProps } from "./Table"; +import { useState, Ref, useImperativeHandle, useEffect, useCallback } from "react"; +import SortableTable, { Pagination, RowsPerPage, SortableTableProps } from "./Table"; import { PrismaClient } from "@repo/db"; import { getData } from "./pagiantedTableActions"; import { useDebounce } from "@repo/shared-components"; @@ -12,7 +12,7 @@ export interface PaginatedTableRef { interface PaginatedTableProps extends Omit, "data"> { prismaModel: keyof PrismaClient; filter?: Record; - rowsPerPage?: number; + initialRowsPerPage?: number; searchFields?: string[]; include?: Record; strictQuery?: boolean; @@ -25,7 +25,7 @@ interface PaginatedTableProps extends Omit, "da export function PaginatedTable({ prismaModel, - rowsPerPage = 10, + initialRowsPerPage = 30, searchFields = [], filter, include, @@ -38,6 +38,7 @@ export function PaginatedTable({ ...restProps }: PaginatedTableProps) { const [data, setData] = useState([]); + const [rowsPerPage, setRowsPerPage] = useState(initialRowsPerPage); const [page, setPage] = useState(0); const [total, setTotal] = useState(0); const [searchTerm, setSearchTerm] = useState(""); @@ -52,8 +53,10 @@ export function PaginatedTable({ ) : {}, ); + const [loading, setLoading] = useState(false); - const RefreshTableData = async () => { + const refreshTableData = useCallback(async () => { + setLoading(true); getData( prismaModel, rowsPerPage, @@ -75,23 +78,43 @@ export function PaginatedTable({ return acc; }, {}) : undefined, - ).then((result) => { - if (result) { - setData(result.data); - setTotal(result.total); - } - }); - }; + ) + .then((result) => { + if (result) { + setData(result.data); + setTotal(result.total); + } + }) + .finally(() => { + setLoading(false); + }); + }, [ + prismaModel, + rowsPerPage, + page, + searchTerm, + searchFields, + filter, + include, + orderBy, + strictQuery, + restProps.columns, + ]); useImperativeHandle(ref, () => ({ refresh: () => { - RefreshTableData(); + refreshTableData(); }, })); + // useEffect to show loading spinner + useEffect(() => { + setLoading(true); + }, [searchTerm, page, rowsPerPage, orderBy, filter, setLoading, refreshTableData]); + useDebounce( () => { - RefreshTableData(); + refreshTableData(); }, 500, [searchTerm, page, rowsPerPage, orderBy, filter], @@ -100,7 +123,10 @@ export function PaginatedTable({ return (
-
{leftOfSearch}
+
+
{leftOfSearch}
+
{loading && }
+
{searchFields.length > 0 && ( ({
{leftOfPagination} {!hide && ( - + <> + + + )}
diff --git a/apps/hub/app/_components/Table.tsx b/apps/hub/app/_components/Table.tsx index 3a0e6d5f..115dfce4 100644 --- a/apps/hub/app/_components/Table.tsx +++ b/apps/hub/app/_components/Table.tsx @@ -86,6 +86,28 @@ export default function SortableTable({ ); } +export const RowsPerPage = ({ + rowsPerPage, + setRowsPerPage, +}: { + rowsPerPage: number; + setRowsPerPage: (rowsPerPage: number) => void; +}) => { + return ( + + ); +}; + export const Pagination = ({ page, totalPages,