Lade-anzeige für Tabellen
This commit is contained in:
@@ -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<TData> extends Omit<SortableTableProps<TData>, "data"> {
|
||||
prismaModel: keyof PrismaClient;
|
||||
filter?: Record<string, unknown>;
|
||||
rowsPerPage?: number;
|
||||
initialRowsPerPage?: number;
|
||||
searchFields?: string[];
|
||||
include?: Record<string, boolean>;
|
||||
strictQuery?: boolean;
|
||||
@@ -25,7 +25,7 @@ interface PaginatedTableProps<TData> extends Omit<SortableTableProps<TData>, "da
|
||||
|
||||
export function PaginatedTable<TData>({
|
||||
prismaModel,
|
||||
rowsPerPage = 10,
|
||||
initialRowsPerPage = 30,
|
||||
searchFields = [],
|
||||
filter,
|
||||
include,
|
||||
@@ -38,6 +38,7 @@ export function PaginatedTable<TData>({
|
||||
...restProps
|
||||
}: PaginatedTableProps<TData>) {
|
||||
const [data, setData] = useState<TData[]>([]);
|
||||
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<TData>({
|
||||
)
|
||||
: {},
|
||||
);
|
||||
const [loading, setLoading] = useState(false);
|
||||
|
||||
const RefreshTableData = async () => {
|
||||
const refreshTableData = useCallback(async () => {
|
||||
setLoading(true);
|
||||
getData(
|
||||
prismaModel,
|
||||
rowsPerPage,
|
||||
@@ -75,23 +78,43 @@ export function PaginatedTable<TData>({
|
||||
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<TData>({
|
||||
return (
|
||||
<div className="space-y-4 m-4">
|
||||
<div className="flex items-center gap-2">
|
||||
<div className="flex-1">{leftOfSearch}</div>
|
||||
<div className="flex-1 flex gap-2">
|
||||
<div>{leftOfSearch}</div>
|
||||
<div>{loading && <span className="loading loading-dots loading-md" />}</div>
|
||||
</div>
|
||||
{searchFields.length > 0 && (
|
||||
<input
|
||||
type="text"
|
||||
@@ -126,7 +152,10 @@ export function PaginatedTable<TData>({
|
||||
<div className="flex items-between">
|
||||
{leftOfPagination}
|
||||
{!hide && (
|
||||
<Pagination totalPages={Math.ceil(total / rowsPerPage)} page={page} setPage={setPage} />
|
||||
<>
|
||||
<RowsPerPage rowsPerPage={rowsPerPage} setRowsPerPage={setRowsPerPage} />
|
||||
<Pagination totalPages={Math.ceil(total / rowsPerPage)} page={page} setPage={setPage} />
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -86,6 +86,28 @@ export default function SortableTable<TData>({
|
||||
);
|
||||
}
|
||||
|
||||
export const RowsPerPage = ({
|
||||
rowsPerPage,
|
||||
setRowsPerPage,
|
||||
}: {
|
||||
rowsPerPage: number;
|
||||
setRowsPerPage: (rowsPerPage: number) => void;
|
||||
}) => {
|
||||
return (
|
||||
<select
|
||||
className="select w-32"
|
||||
value={rowsPerPage}
|
||||
onChange={(e) => setRowsPerPage(Number(e.target.value))}
|
||||
>
|
||||
<option value={10}>10</option>
|
||||
<option value={30}>30</option>
|
||||
<option value={50}>50</option>
|
||||
<option value={100}>100</option>
|
||||
<option value={300}>300</option>
|
||||
</select>
|
||||
);
|
||||
};
|
||||
|
||||
export const Pagination = ({
|
||||
page,
|
||||
totalPages,
|
||||
|
||||
Reference in New Issue
Block a user