simplify the Table component, the UsersPage shows some basic data
This commit is contained in:
parent
987a7b46f6
commit
970d962ca5
|
@ -6,7 +6,6 @@ import {
|
|||
Table as MUITable,
|
||||
TableBody,
|
||||
TableProps as MUITableProps,
|
||||
TableBodyProps,
|
||||
TableContainer,
|
||||
} from '@material-ui/core';
|
||||
import TableHead from './TableHead';
|
||||
|
@ -23,18 +22,15 @@ export interface TableProps<T> {
|
|||
orderDirection?: OrderDirection;
|
||||
selection?: boolean;
|
||||
idFieldName?: string;
|
||||
getRowKey?: (row: T, index: number) => string | number | null | undefined;
|
||||
onRequestSort?: (
|
||||
orderBy: string,
|
||||
orderDirection: OrderDirection
|
||||
) => void | Promise<void>;
|
||||
onSelect?: (rows: T[]) => void;
|
||||
loading?: boolean;
|
||||
tableProps?: MUITableProps;
|
||||
tableBodyProps?: TableBodyProps;
|
||||
footerProps?: TableFooterProps;
|
||||
hideFooter?: boolean;
|
||||
size?: 'medium' | 'small';
|
||||
size?: MUITableProps['size'];
|
||||
selected?: T[];
|
||||
}
|
||||
|
||||
|
@ -48,19 +44,12 @@ function Table<T>({
|
|||
selection = false,
|
||||
loading = false,
|
||||
actions = [],
|
||||
tableBodyProps = {},
|
||||
tableProps = {},
|
||||
hideFooter = false,
|
||||
footerProps = {},
|
||||
size,
|
||||
selected,
|
||||
onSelect,
|
||||
getRowKey,
|
||||
}: TableProps<T>) {
|
||||
const headColumns =
|
||||
actions.length > 0
|
||||
? [...columns, { field: 'action', label: 'Akcje' }]
|
||||
: columns;
|
||||
const preparedFooterProps = {
|
||||
page: 0,
|
||||
rowsPerPage: validateRowsPerPage(
|
||||
|
@ -86,11 +75,12 @@ function Table<T>({
|
|||
|
||||
return (
|
||||
<TableContainer>
|
||||
<MUITable size={size} {...tableProps}>
|
||||
<MUITable size={size}>
|
||||
<TableHead
|
||||
columns={headColumns}
|
||||
columns={columns}
|
||||
selection={selection}
|
||||
orderBy={orderBy}
|
||||
hasActions={actions.length > 0}
|
||||
orderDirection={orderDirection}
|
||||
onRequestSort={onRequestSort}
|
||||
size={size}
|
||||
|
@ -101,10 +91,9 @@ function Table<T>({
|
|||
}}
|
||||
allSelected={selected?.length === data.length}
|
||||
/>
|
||||
<TableBody {...tableBodyProps}>
|
||||
<TableBody>
|
||||
{loading ? (
|
||||
<TableLoading
|
||||
columns={headColumns}
|
||||
size={size}
|
||||
rowsPerPage={preparedFooterProps.rowsPerPage}
|
||||
/>
|
||||
|
@ -113,11 +102,7 @@ function Table<T>({
|
|||
return (
|
||||
<TableRow
|
||||
key={
|
||||
getRowKey
|
||||
? getRowKey(item, index)
|
||||
: isObjKey(item, idFieldName)
|
||||
? item[idFieldName] + ''
|
||||
: index
|
||||
isObjKey(item, idFieldName) ? item[idFieldName] + '' : index
|
||||
}
|
||||
index={index}
|
||||
row={item}
|
||||
|
|
|
@ -4,6 +4,7 @@ import {
|
|||
TablePagination,
|
||||
TableRow,
|
||||
TableFooter as MUITableFooter,
|
||||
TablePaginationProps as MUITablePaginationProps,
|
||||
} from '@material-ui/core';
|
||||
|
||||
export interface TableFooterProps {
|
||||
|
@ -12,8 +13,8 @@ export interface TableFooterProps {
|
|||
onChangePage?: (page: number) => void;
|
||||
rowsPerPage?: number;
|
||||
onChangeRowsPerPage?: (limit: number) => void;
|
||||
rowsPerPageOptions?: Array<number | { value: number; label: string }>;
|
||||
size?: 'small' | 'medium';
|
||||
rowsPerPageOptions?: MUITablePaginationProps['rowsPerPageOptions'];
|
||||
size?: MUITablePaginationProps['size'];
|
||||
}
|
||||
|
||||
export const ROWS_PER_PAGE_DEFAULT = 25;
|
||||
|
|
|
@ -22,6 +22,7 @@ export interface TableHeadProps {
|
|||
property: string,
|
||||
orderDirection: OrderDirection
|
||||
) => void | Promise<void>;
|
||||
hasActions: boolean;
|
||||
}
|
||||
|
||||
function TableHead({
|
||||
|
@ -33,6 +34,7 @@ function TableHead({
|
|||
allSelected = false,
|
||||
onRequestSort,
|
||||
size = 'medium',
|
||||
hasActions = false,
|
||||
}: TableHeadProps) {
|
||||
const createSortHandler = (property: string) => () => {
|
||||
if (onRequestSort) {
|
||||
|
@ -85,6 +87,7 @@ function TableHead({
|
|||
</TableCell>
|
||||
);
|
||||
})}
|
||||
{hasActions && <TableCell size={size}>Akcje</TableCell>}
|
||||
</TableRow>
|
||||
</MUITableHead>
|
||||
);
|
||||
|
|
|
@ -1,30 +1,22 @@
|
|||
import React, { Fragment } from 'react';
|
||||
import { Column } from './types';
|
||||
|
||||
import { TableRow, TableCell } from '@material-ui/core';
|
||||
import { Skeleton } from '@material-ui/lab';
|
||||
|
||||
export interface TableLoadingProps {
|
||||
rowsPerPage: number;
|
||||
columns: Column[];
|
||||
size?: 'small' | 'medium';
|
||||
}
|
||||
|
||||
function TableLoading({
|
||||
rowsPerPage,
|
||||
columns,
|
||||
size = 'medium',
|
||||
}: TableLoadingProps) {
|
||||
function TableLoading({ rowsPerPage, size = 'medium' }: TableLoadingProps) {
|
||||
return (
|
||||
<Fragment>
|
||||
{new Array(rowsPerPage).fill(0).map((_, index) => {
|
||||
return (
|
||||
<TableRow key={index}>
|
||||
{columns.map(col => (
|
||||
<TableCell size={size} key={col.field}>
|
||||
<Skeleton variant="text" />
|
||||
</TableCell>
|
||||
))}
|
||||
<TableCell size={size} colSpan={100}>
|
||||
<Skeleton variant="text" />
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
);
|
||||
})}
|
||||
|
|
|
@ -1,13 +1,12 @@
|
|||
import {
|
||||
ROWS_PER_PAGE_DEFAULT,
|
||||
ROWS_PER_PAGE_OPTIONS_DEFAULT,
|
||||
TableFooterProps,
|
||||
} from './TableFooter';
|
||||
|
||||
export const validateRowsPerPage = (
|
||||
rowsPerPage: number | null = ROWS_PER_PAGE_DEFAULT,
|
||||
rowsPerPageOptions: Array<
|
||||
number | { value: number; label: string }
|
||||
> = ROWS_PER_PAGE_OPTIONS_DEFAULT
|
||||
rowsPerPageOptions: TableFooterProps['rowsPerPageOptions'] = ROWS_PER_PAGE_OPTIONS_DEFAULT
|
||||
) => {
|
||||
const opt =
|
||||
rowsPerPageOptions.find(opt =>
|
||||
|
|
|
@ -2,20 +2,52 @@ import useUsers from './UsersPage.useUsers';
|
|||
import { NumberParam, useQueryParams, withDefault } from 'use-query-params';
|
||||
import SortParam, { decodeSort } from 'libs/serialize-query-params/SortParam';
|
||||
import { validateRowsPerPage } from 'common/Table/helpers';
|
||||
import { DEFAULT_SORT, COLUMNS } from './constants';
|
||||
|
||||
const DEFAULT_SORT = decodeSort('id DESC');
|
||||
import { Container, Paper } from '@material-ui/core';
|
||||
import Table from 'common/Table/Table';
|
||||
|
||||
const UsersPage = () => {
|
||||
const [{ page, sort, ...rest }, setQuery] = useQueryParams({
|
||||
const [{ page, sort, ...rest }, setQueryParams] = useQueryParams({
|
||||
limit: NumberParam,
|
||||
page: withDefault(NumberParam, 0),
|
||||
sort: withDefault(SortParam, DEFAULT_SORT),
|
||||
});
|
||||
const limit = validateRowsPerPage(rest.limit);
|
||||
const data = useUsers(page, limit, sort.toString());
|
||||
console.log(data);
|
||||
const { users, total, loading } = useUsers(page, limit, sort.toString());
|
||||
console.log(users);
|
||||
|
||||
return <div>UsersPage</div>;
|
||||
return (
|
||||
<Container>
|
||||
<Paper>
|
||||
<Table
|
||||
selection
|
||||
columns={COLUMNS}
|
||||
data={users}
|
||||
loading={loading}
|
||||
orderBy={sort.orderBy}
|
||||
orderDirection={sort.orderDirection}
|
||||
onRequestSort={(orderBy, orderDirection) => {
|
||||
setQueryParams({
|
||||
page: 0,
|
||||
sort: decodeSort(orderBy + ' ' + orderDirection),
|
||||
});
|
||||
}}
|
||||
footerProps={{
|
||||
count: total,
|
||||
page,
|
||||
onChangePage: page => {
|
||||
setQueryParams({ page });
|
||||
},
|
||||
onChangeRowsPerPage: limit => {
|
||||
setQueryParams({ page: 0, limit });
|
||||
},
|
||||
rowsPerPage: limit,
|
||||
}}
|
||||
/>
|
||||
</Paper>
|
||||
</Container>
|
||||
);
|
||||
};
|
||||
|
||||
export default UsersPage;
|
||||
|
|
|
@ -18,7 +18,7 @@ const useUsers = (page: number, limit: number, sort: string) => {
|
|||
return {
|
||||
users: data?.users.items ?? [],
|
||||
get loading() {
|
||||
return this.users.length === 0 || loading;
|
||||
return this.users.length === 0 && loading;
|
||||
},
|
||||
total: data?.users.total ?? 0,
|
||||
};
|
||||
|
|
|
@ -0,0 +1,39 @@
|
|||
import { decodeSort } from 'libs/serialize-query-params/SortParam';
|
||||
import { formatRole } from './utils';
|
||||
import { Column } from 'common/Table/types';
|
||||
import { User } from 'libs/graphql/types';
|
||||
|
||||
export const DEFAULT_SORT = decodeSort('id DESC');
|
||||
export const COLUMNS: Column<User>[] = [
|
||||
{
|
||||
field: 'id',
|
||||
sortable: true,
|
||||
label: 'ID',
|
||||
},
|
||||
{
|
||||
field: 'displayName',
|
||||
sortable: true,
|
||||
label: 'Użytkownik',
|
||||
valueFormatter: v => {
|
||||
return `${v.displayName} (${v.email})`;
|
||||
},
|
||||
},
|
||||
{
|
||||
field: 'role',
|
||||
sortable: false,
|
||||
label: 'Rola',
|
||||
valueFormatter: v => formatRole(v.role),
|
||||
},
|
||||
{
|
||||
field: 'activated',
|
||||
sortable: false,
|
||||
label: 'Aktywowany',
|
||||
valueFormatter: v => (v.activated ? 'Tak' : 'Nie'),
|
||||
},
|
||||
{
|
||||
field: 'createdAt',
|
||||
sortable: true,
|
||||
label: 'Data utworzenia',
|
||||
type: 'datetime',
|
||||
},
|
||||
];
|
|
@ -15,6 +15,7 @@ export const QUERY_USERS = gql`
|
|||
displayName
|
||||
email
|
||||
role
|
||||
createdAt
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
import { Role } from '../../libs/graphql/types';
|
||||
|
||||
export const formatRole = (r: Role): string =>
|
||||
r === Role.Admin ? 'Admin' : 'Użytkownik';
|
Reference in New Issue