Initial dev on DataTable component.

This commit is contained in:
Mike Cao 2023-08-25 11:54:44 -07:00
parent 7107336b49
commit d6a27b8e99
19 changed files with 223 additions and 53 deletions

View file

@ -0,0 +1,68 @@
import { createContext } from 'react';
import { SearchField } from 'react-basics';
import { useDataTable } from 'components/hooks/useDataTable';
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 = 1000;
export const DataTableStyles = styles;
export const DataTableContext = createContext(null);
export function DataTable({
searchDelay,
showSearch = true,
showPaging = true,
children,
onChange,
}) {
const { formatMessage, labels, messages } = useMessages();
const dataTable = useDataTable();
const { query, setQuery, data, pageInfo, setPageInfo } = dataTable;
const { page, pageSize, count } = pageInfo || {};
const noResults = Boolean(query && data?.length === 0);
const handleChange = () => {
onChange?.({ query, page });
};
const handleSearch = value => {
setQuery(value);
handleChange();
};
const handlePageChange = page => {
setPageInfo(state => ({ ...state, page }));
};
return (
<DataTableContext.Provider value={dataTable}>
{showSearch && (
<SearchField
className={styles.search}
value={query}
onChange={handleSearch}
delay={searchDelay || DEFAULT_SEARCH_DELAY}
autoFocus={true}
placeholder={formatMessage(labels.search)}
/>
)}
{noResults && <Empty message={formatMessage(messages.noResultsFound)} />}
<div className={styles.body}>{children}</div>
{showPaging && (
<Pager
className={styles.pager}
page={page}
pageSize={pageSize}
count={count}
onPageChange={handlePageChange}
/>
)}
</DataTableContext.Provider>
);
}
export default DataTable;

View file

@ -0,0 +1,17 @@
.search {
max-width: 300px;
margin: 20px 0;
}
.action {
justify-content: flex-end;
gap: 5px;
}
.body td {
align-items: center;
}
.pager {
margin-top: 20px;
}

View file

@ -1,14 +1,15 @@
import styles from './Pager.module.css';
import classNames from 'classnames';
import { Button, Flexbox, Icon, Icons } from 'react-basics';
import useMessages from 'components/hooks/useMessages';
import styles from './Pager.module.css';
export function Pager({ page, pageSize, count, onPageChange }) {
export function Pager({ page, pageSize, count, onPageChange, className }) {
const { formatMessage, labels } = useMessages();
const maxPage = Math.ceil(count / pageSize);
const maxPage = pageSize && count ? Math.ceil(count / pageSize) : 0;
const lastPage = page === maxPage;
const firstPage = page === 1;
if (count === 0) {
if (count === 0 || !maxPage) {
return null;
}
@ -24,7 +25,7 @@ export function Pager({ page, pageSize, count, onPageChange }) {
}
return (
<Flexbox justifyContent="center" className={styles.container}>
<Flexbox justifyContent="center" className={classNames(styles.container, className)}>
<Button onClick={() => handlePageChange(-1)} disabled={firstPage}>
<Icon rotate={90}>
<Icons.ChevronDown />

View file

@ -1,7 +1,4 @@
.container {
margin-top: 20px;
}
.text {
font-size: var(--font-size-md);
margin: 0 16px;
}