mirror of
https://github.com/umami-software/umami.git
synced 2026-02-07 14:17:13 +01:00
Refactored to use app folder.
This commit is contained in:
parent
40cfcd41e9
commit
9a52cdd2e1
258 changed files with 2025 additions and 2258 deletions
95
src/components/common/DataTable.tsx
Normal file
95
src/components/common/DataTable.tsx
Normal file
|
|
@ -0,0 +1,95 @@
|
|||
import { ReactNode, Dispatch, SetStateAction } from 'react';
|
||||
import classNames from 'classnames';
|
||||
import { Banner, Loading, SearchField } from 'react-basics';
|
||||
import { useMessages } from 'components/hooks';
|
||||
import Empty from 'components/common/Empty';
|
||||
import Pager from 'components/common/Pager';
|
||||
import styles from './DataTable.module.css';
|
||||
|
||||
const DEFAULT_SEARCH_DELAY = 600;
|
||||
|
||||
export interface DataTableProps {
|
||||
result: {
|
||||
page: number;
|
||||
pageSize: number;
|
||||
count: number;
|
||||
data: any[];
|
||||
};
|
||||
params: {
|
||||
query: string;
|
||||
page: number;
|
||||
};
|
||||
setParams: Dispatch<SetStateAction<{ query: string; page: number }>>;
|
||||
isLoading: boolean;
|
||||
error: unknown;
|
||||
searchDelay?: number;
|
||||
showSearch?: boolean;
|
||||
showPaging?: boolean;
|
||||
children: ReactNode | ((data: any) => ReactNode);
|
||||
}
|
||||
|
||||
export function DataTable({
|
||||
result,
|
||||
params,
|
||||
setParams,
|
||||
isLoading,
|
||||
error,
|
||||
searchDelay,
|
||||
showSearch = true,
|
||||
showPaging = true,
|
||||
children,
|
||||
}: DataTableProps) {
|
||||
const { formatMessage, labels, messages } = useMessages();
|
||||
const { pageSize, count } = result || {};
|
||||
const { query, page } = params || {};
|
||||
const hasData = Boolean(!isLoading && result?.data?.length);
|
||||
const noResults = Boolean(!isLoading && query && !hasData);
|
||||
|
||||
const handleSearch = query => {
|
||||
setParams({ ...params, query });
|
||||
};
|
||||
|
||||
const handlePageChange = page => {
|
||||
setParams({ ...params, page });
|
||||
};
|
||||
|
||||
if (error) {
|
||||
return <Banner variant="error">{formatMessage(messages.error)}</Banner>;
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
{(hasData || query || isLoading) && showSearch && (
|
||||
<SearchField
|
||||
className={styles.search}
|
||||
value={query}
|
||||
onChange={handleSearch}
|
||||
delay={searchDelay || DEFAULT_SEARCH_DELAY}
|
||||
autoFocus={true}
|
||||
placeholder={formatMessage(labels.search)}
|
||||
/>
|
||||
)}
|
||||
<div
|
||||
className={classNames(styles.body, { [styles.status]: isLoading || noResults || !hasData })}
|
||||
>
|
||||
{hasData ? (typeof children === 'function' ? children(result) : children) : null}
|
||||
{isLoading && <Loading icon="dots" />}
|
||||
{!isLoading && !hasData && !query && (
|
||||
<Empty message={formatMessage(messages.noDataAvailable)} />
|
||||
)}
|
||||
{noResults && <Empty message={formatMessage(messages.noResultsFound)} />}
|
||||
</div>
|
||||
{showPaging && (
|
||||
<Pager
|
||||
className={styles.pager}
|
||||
page={page}
|
||||
pageSize={pageSize}
|
||||
count={count}
|
||||
onPageChange={handlePageChange}
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
export default DataTable;
|
||||
Loading…
Add table
Add a link
Reference in a new issue